This is an automated email from the ASF dual-hosted git repository.

wangdan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pegasus.git


The following commit(s) were added to refs/heads/master by this push:
     new 10167d19e feat(dns_resolver): add metrics for dns_resolver (#1873)
10167d19e is described below

commit 10167d19ed27beb9cd153633e70c81ed02102c1f
Author: Yingchun Lai <[email protected]>
AuthorDate: Tue Jan 30 15:26:23 2024 +0800

    feat(dns_resolver): add metrics for dns_resolver (#1873)
    
    The DNS resolve function maybe slow, and the memory size of dns_resolver is
    not limited currently, this patch adds 3 useful metrics to improve 
observability:
    - dns_resolver_cache_size
    - dns_resolver_resolve_duration_ns
    - dns_resolver_resolve_by_dns_duration_ns
---
 src/runtime/rpc/dns_resolver.cpp  | 73 ++++++++++++++++++++++++++++-----------
 src/runtime/rpc/dns_resolver.h    | 21 +++++++----
 src/runtime/rpc/rpc_host_port.cpp |  3 ++
 3 files changed, 71 insertions(+), 26 deletions(-)

diff --git a/src/runtime/rpc/dns_resolver.cpp b/src/runtime/rpc/dns_resolver.cpp
index 8ccbdac56..06bf4aca1 100644
--- a/src/runtime/rpc/dns_resolver.cpp
+++ b/src/runtime/rpc/dns_resolver.cpp
@@ -19,27 +19,52 @@
 
 #include <algorithm>
 #include <memory>
+#include <set>
 #include <utility>
 
+#include "absl/strings/string_view.h"
+#include "fmt/core.h"
 #include "fmt/format.h"
 #include "runtime/rpc/dns_resolver.h"
 #include "runtime/rpc/group_address.h"
 #include "runtime/rpc/group_host_port.h"
+#include "utils/autoref_ptr.h"
 #include "utils/fmt_logging.h"
 
+METRIC_DEFINE_gauge_int64(server,
+                          dns_resolver_cache_size,
+                          dsn::metric_unit::kKeys,
+                          "The size of the host_port to rpc_address resolve 
results cache");
+
+METRIC_DEFINE_percentile_int64(
+    server,
+    dns_resolver_resolve_duration_ns,
+    dsn::metric_unit::kNanoSeconds,
+    "The duration of resolving a host port, may either get from cache or 
resolve by DNS lookup");
+
+METRIC_DEFINE_percentile_int64(server,
+                               dns_resolver_resolve_by_dns_duration_ns,
+                               dsn::metric_unit::kNanoSeconds,
+                               "The duration of resolving a host port by DNS 
lookup");
 namespace dsn {
 
-void dns_resolver::add_item(const host_port &hp, const rpc_address &addr)
+dns_resolver::dns_resolver()
+    : METRIC_VAR_INIT_server(dns_resolver_cache_size),
+      METRIC_VAR_INIT_server(dns_resolver_resolve_duration_ns),
+      METRIC_VAR_INIT_server(dns_resolver_resolve_by_dns_duration_ns)
 {
-    utils::auto_write_lock l(_lock);
-    _dsn_cache.insert(std::make_pair(hp, addr));
+#ifndef MOCK_TEST
+    static int only_one_instance = 0;
+    only_one_instance++;
+    CHECK_EQ_MSG(1, only_one_instance, "dns_resolver should only created 
once!");
+#endif
 }
 
 bool dns_resolver::get_cached_addresses(const host_port &hp, 
std::vector<rpc_address> &addresses)
 {
     utils::auto_read_lock l(_lock);
-    const auto &found = _dsn_cache.find(hp);
-    if (found == _dsn_cache.end()) {
+    const auto &found = _dns_cache.find(hp);
+    if (found == _dns_cache.end()) {
         return false;
     }
 
@@ -55,19 +80,26 @@ error_s dns_resolver::resolve_addresses(const host_port 
&hp, std::vector<rpc_add
     }
 
     std::vector<rpc_address> resolved_addresses;
-    RETURN_NOT_OK(hp.resolve_addresses(resolved_addresses));
+    {
+        METRIC_VAR_AUTO_LATENCY(dns_resolver_resolve_by_dns_duration_ns);
+        RETURN_NOT_OK(hp.resolve_addresses(resolved_addresses));
+    }
 
     {
-        utils::auto_write_lock l(_lock);
         if (resolved_addresses.size() > 1) {
-            LOG_DEBUG(
-                "host_port '{}' resolves to {} different addresses {}, using 
the first one {}.",
-                hp,
-                resolved_addresses.size(),
-                fmt::join(resolved_addresses, ","),
-                resolved_addresses[0]);
+            LOG_DEBUG("host_port '{}' resolves to {} different addresses {}, 
only the first one {} "
+                      "will be cached.",
+                      hp,
+                      resolved_addresses.size(),
+                      fmt::join(resolved_addresses, ","),
+                      resolved_addresses[0]);
+        }
+
+        utils::auto_write_lock l(_lock);
+        const auto it = _dns_cache.insert(std::make_pair(hp, 
resolved_addresses[0]));
+        if (it.second) {
+            METRIC_VAR_INCREMENT(dns_resolver_cache_size);
         }
-        _dsn_cache.insert(std::make_pair(hp, resolved_addresses[0]));
     }
 
     addresses = std::move(resolved_addresses);
@@ -76,18 +108,19 @@ error_s dns_resolver::resolve_addresses(const host_port 
&hp, std::vector<rpc_add
 
 rpc_address dns_resolver::resolve_address(const host_port &hp)
 {
+    METRIC_VAR_AUTO_LATENCY(dns_resolver_resolve_duration_ns);
     switch (hp.type()) {
     case HOST_TYPE_GROUP: {
         rpc_address addr;
-        auto group_address = hp.group_host_port();
-        addr.assign_group(group_address->name());
+        auto hp_group = hp.group_host_port();
+        addr.assign_group(hp_group->name());
 
-        for (const auto &hp : group_address->members()) {
+        for (const auto &hp : hp_group->members()) {
             CHECK_TRUE(addr.group_address()->add(resolve_address(hp)));
         }
         addr.group_address()->set_update_leader_automatically(
-            group_address->is_update_leader_automatically());
-        
addr.group_address()->set_leader(resolve_address(group_address->leader()));
+            hp_group->is_update_leader_automatically());
+        addr.group_address()->set_leader(resolve_address(hp_group->leader()));
         return addr;
     }
     case HOST_TYPE_IPV4: {
@@ -104,7 +137,7 @@ rpc_address dns_resolver::resolve_address(const host_port 
&hp)
         return addresses[0];
     }
     default:
-        return rpc_address();
+        return {};
     }
 }
 
diff --git a/src/runtime/rpc/dns_resolver.h b/src/runtime/rpc/dns_resolver.h
index 7cf47895c..aadb3287f 100644
--- a/src/runtime/rpc/dns_resolver.h
+++ b/src/runtime/rpc/dns_resolver.h
@@ -25,17 +25,22 @@
 #include "runtime/rpc/rpc_address.h"
 #include "runtime/rpc/rpc_host_port.h"
 #include "utils/errors.h"
+#include "utils/metrics.h"
 #include "utils/synchronize.h"
 
 namespace dsn {
 
 // This class provide a way to resolve host_port to rpc_address.
+// Now each host_post will be resolved just once, and then cached the first 
rpc_address result in
+// the resolved result list.
+// If some host_port's rpc_address changes, you need to restart the Pegasus 
process to make it take
+// effect.
+// TODO(yingchun): Now the cache is unlimited, the cache size may be huge. 
Implement an expiration
+// mechanism to limit the cache size and make it possible to update the 
resolve result.
 class dns_resolver
 {
 public:
-    explicit dns_resolver() = default;
-
-    void add_item(const host_port &hp, const rpc_address &addr);
+    explicit dns_resolver();
 
     // Resolve this host_port to an unique rpc_address.
     rpc_address resolve_address(const host_port &hp);
@@ -45,10 +50,14 @@ private:
 
     error_s resolve_addresses(const host_port &hp, std::vector<rpc_address> 
&addresses);
 
-    error_s do_resolution(const host_port &hp, std::vector<rpc_address> 
&addresses);
-
     mutable utils::rw_lock_nr _lock;
-    std::unordered_map<host_port, rpc_address> _dsn_cache;
+    // Cache the host_port resolve results, the cached rpc_address is the 
first one in the resolved
+    // list.
+    std::unordered_map<host_port, rpc_address> _dns_cache;
+
+    METRIC_VAR_DECLARE_gauge_int64(dns_resolver_cache_size);
+    METRIC_VAR_DECLARE_percentile_int64(dns_resolver_resolve_duration_ns);
+    
METRIC_VAR_DECLARE_percentile_int64(dns_resolver_resolve_by_dns_duration_ns);
 };
 
 } // namespace dsn
diff --git a/src/runtime/rpc/rpc_host_port.cpp 
b/src/runtime/rpc/rpc_host_port.cpp
index 2da05e7b8..8be334fd2 100644
--- a/src/runtime/rpc/rpc_host_port.cpp
+++ b/src/runtime/rpc/rpc_host_port.cpp
@@ -180,6 +180,9 @@ error_s 
host_port::resolve_addresses(std::vector<rpc_address> &addresses) const
         return error_s::make(dsn::ERR_INVALID_STATE, "invalid host_port type: 
HOST_TYPE_GROUP");
     case HOST_TYPE_IPV4:
         break;
+    default:
+        CHECK(false, "");
+        __builtin_unreachable();
     }
 
     rpc_address rpc_addr;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to