From: Xiubo Li Date: Fri, 5 Jun 2020 00:48:59 +0000 (-0400) Subject: mds: add dentry lease metric payload support X-Git-Tag: v16.1.0~687^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b4cc30617d15d94fb947f9933c54499689ebbeb0;p=ceph.git mds: add dentry lease metric payload support Fixes: https://tracker.ceph.com/issues/43423 Signed-off-by: Xiubo Li --- diff --git a/src/client/Client.cc b/src/client/Client.cc index c4c3fec2cf3..13ac12deecb 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -3195,6 +3195,7 @@ Dentry* Client::link(Dir *dir, const string& name, Inode *in, Dentry *dn) } dn->link(in); + inc_dentry_nr(); ldout(cct, 20) << "link inode " << in << " parents now " << in->dentries << dendl; } @@ -3210,6 +3211,7 @@ void Client::unlink(Dentry *dn, bool keepdir, bool keepdentry) // unlink from inode if (dn->inode) { dn->unlink(); + dec_dentry_nr(); ldout(cct, 20) << "unlink inode " << in << " parents now " << in->dentries << dendl; } @@ -6540,6 +6542,11 @@ void Client::collect_and_send_global_metrics() { metric = ClientMetricMessage(CapInfoPayload(cap_hits, cap_misses, 0)); message.push_back(metric); + // dentry lease hit ratio + auto [dlease_hits, dlease_misses, nr] = get_dlease_hit_rates(); + metric = ClientMetricMessage(DentryLeasePayload(dlease_hits, dlease_misses, nr)); + message.push_back(metric); + session->con->send_message2(make_message(std::move(message))); } @@ -6597,13 +6604,16 @@ bool Client::_dentry_valid(const Dentry *dn) if (dn->lease_mds >= 0 && dn->lease_ttl > now && mds_sessions.count(dn->lease_mds)) { MetaSession &s = mds_sessions.at(dn->lease_mds); - if (s.cap_ttl > now && s.cap_gen == dn->lease_gen) + if (s.cap_ttl > now && s.cap_gen == dn->lease_gen) { + dlease_hit(); return true; + } ldout(cct, 20) << " bad lease, cap_ttl " << s.cap_ttl << ", cap_gen " << s.cap_gen << " vs lease_gen " << dn->lease_gen << dendl; } + dlease_miss(); return false; } diff --git a/src/client/Client.h b/src/client/Client.h index 4d50bf9b7ad..5bb8e613284 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -739,6 +739,22 @@ public: void flush_cap_releases(); void tick(); + void inc_dentry_nr() { + ++dentry_nr; + } + void dec_dentry_nr() { + --dentry_nr; + } + void dlease_hit() { + ++dlease_hits; + } + void dlease_miss() { + ++dlease_misses; + } + std::tuple get_dlease_hit_rates() { + return std::make_tuple(dlease_hits, dlease_misses, dentry_nr); + } + void cap_hit() { ++cap_hits; } @@ -1424,6 +1440,11 @@ private: epoch_t reclaim_osd_epoch = 0; entity_addrvec_t reclaim_target_addrs; + // dentry lease metrics + uint64_t dentry_nr = 0; + uint64_t dlease_hits = 0; + uint64_t dlease_misses = 0; + uint64_t cap_hits = 0; uint64_t cap_misses = 0; diff --git a/src/include/cephfs/metrics/Types.h b/src/include/cephfs/metrics/Types.h index 01f4d7ed087..5951e8ea199 100644 --- a/src/include/cephfs/metrics/Types.h +++ b/src/include/cephfs/metrics/Types.h @@ -21,6 +21,7 @@ enum ClientMetricType { CLIENT_METRIC_TYPE_READ_LATENCY, CLIENT_METRIC_TYPE_WRITE_LATENCY, CLIENT_METRIC_TYPE_METADATA_LATENCY, + CLIENT_METRIC_TYPE_DENTRY_LEASE, }; inline std::ostream &operator<<(std::ostream &os, const ClientMetricType &type) { switch(type) { @@ -36,6 +37,9 @@ inline std::ostream &operator<<(std::ostream &os, const ClientMetricType &type) case ClientMetricType::CLIENT_METRIC_TYPE_METADATA_LATENCY: os << "METADATA_LATENCY"; break; + case ClientMetricType::CLIENT_METRIC_TYPE_DENTRY_LEASE: + os << "DENTRY_LEASE"; + break; default: ceph_abort(); } @@ -167,6 +171,49 @@ struct MetadataLatencyPayload { } }; +struct DentryLeasePayload { + static const ClientMetricType METRIC_TYPE = ClientMetricType::CLIENT_METRIC_TYPE_DENTRY_LEASE; + + uint64_t dlease_hits = 0; + uint64_t dlease_misses = 0; + uint64_t nr_dentries = 0; + + DentryLeasePayload() { } + DentryLeasePayload(uint64_t dlease_hits, uint64_t dlease_misses, uint64_t nr_dentries) + : dlease_hits(dlease_hits), dlease_misses(dlease_misses), nr_dentries(nr_dentries) { + } + + void encode(bufferlist &bl) const { + using ceph::encode; + ENCODE_START(1, 1, bl); + encode(dlease_hits, bl); + encode(dlease_misses, bl); + encode(nr_dentries, bl); + ENCODE_FINISH(bl); + } + + void decode(bufferlist::const_iterator &iter) { + using ceph::decode; + DECODE_START(1, iter); + decode(dlease_hits, iter); + decode(dlease_misses, iter); + decode(nr_dentries, iter); + DECODE_FINISH(iter); + } + + void dump(Formatter *f) const { + f->dump_int("dlease_hits", dlease_hits); + f->dump_int("dlease_misses", dlease_misses); + f->dump_int("num_dentries", nr_dentries); + } + + void print(ostream *out) const { + *out << "dlease_hits: " << dlease_hits << " " + << "dlease_misses: " << dlease_misses << " " + << "num_dentries: " << nr_dentries; + } +}; + struct UnknownPayload { static const ClientMetricType METRIC_TYPE = static_cast(-1); @@ -186,6 +233,7 @@ typedef boost::variant ClientMetricPayload; // metric update message sent by clients @@ -265,6 +313,9 @@ public: case ClientMetricType::CLIENT_METRIC_TYPE_METADATA_LATENCY: payload = MetadataLatencyPayload(); break; + case ClientMetricType::CLIENT_METRIC_TYPE_DENTRY_LEASE: + payload = DentryLeasePayload(); + break; default: payload = UnknownPayload(); break; diff --git a/src/mds/MDSPerfMetricTypes.h b/src/mds/MDSPerfMetricTypes.h index 8ae2f550657..baf8e266d0c 100644 --- a/src/mds/MDSPerfMetricTypes.h +++ b/src/mds/MDSPerfMetricTypes.h @@ -94,10 +94,35 @@ struct MetadataLatencyMetric { } }; +struct DentryLeaseHitMetric { + uint64_t hits = 0; + uint64_t misses = 0; + bool updated = false; + + DENC(DentryLeaseHitMetric, v, p) { + DENC_START(1, 1, p); + denc(v.hits, p); + denc(v.misses, p); + denc(v.updated, p); + DENC_FINISH(p); + } + + void dump(Formatter *f) const { + f->dump_unsigned("hits", hits); + f->dump_unsigned("misses", misses); + } + + friend std::ostream& operator<<(std::ostream& os, const DentryLeaseHitMetric &metric) { + os << "{hits=" << metric.hits << ", misses=" << metric.misses << "}"; + return os; + } +}; + WRITE_CLASS_DENC(CapHitMetric) WRITE_CLASS_DENC(ReadLatencyMetric) WRITE_CLASS_DENC(WriteLatencyMetric) WRITE_CLASS_DENC(MetadataLatencyMetric) +WRITE_CLASS_DENC(DentryLeaseHitMetric) // metrics that are forwarded to the MDS by client(s). struct Metrics { @@ -106,17 +131,21 @@ struct Metrics { ReadLatencyMetric read_latency_metric; WriteLatencyMetric write_latency_metric; MetadataLatencyMetric metadata_latency_metric; + DentryLeaseHitMetric dentry_lease_metric; // metric update type uint32_t update_type = UpdateType::UPDATE_TYPE_REFRESH; DENC(Metrics, v, p) { - DENC_START(1, 1, p); + DENC_START(2, 1, p); denc(v.update_type, p); denc(v.cap_hit_metric, p); denc(v.read_latency_metric, p); denc(v.write_latency_metric, p); denc(v.metadata_latency_metric, p); + if (struct_v >= 2) { + denc(v.dentry_lease_metric, p); + } DENC_FINISH(p); } @@ -126,6 +155,7 @@ struct Metrics { f->dump_object("read_latency_metric", read_latency_metric); f->dump_object("write_latency_metric", write_latency_metric); f->dump_object("metadata_latency_metric", metadata_latency_metric); + f->dump_object("dentry_lease_metric", dentry_lease_metric); } friend std::ostream& operator<<(std::ostream& os, const Metrics& metrics) { @@ -134,6 +164,7 @@ struct Metrics { << ", read_latency=" << metrics.read_latency_metric << ", write_latency=" << metrics.write_latency_metric << ", metadata_latency=" << metrics.metadata_latency_metric + << ", dentry_lease =" << metrics.dentry_lease_metric << "}]"; return os; } diff --git a/src/mds/MetricAggregator.cc b/src/mds/MetricAggregator.cc index aee3bc2473b..23752e90e5d 100644 --- a/src/mds/MetricAggregator.cc +++ b/src/mds/MetricAggregator.cc @@ -126,6 +126,12 @@ void MetricAggregator::refresh_metrics_for_rank(const entity_inst_t &client, c->first = metrics.metadata_latency_metric.lat.tv.tv_sec; c->second = metrics.metadata_latency_metric.lat.tv.tv_nsec; break; + case MDSPerformanceCounterType::DENTRY_LEASE_METRIC: + if (metrics.dentry_lease_metric.updated) { + c->first = metrics.dentry_lease_metric.hits; + c->second = metrics.dentry_lease_metric.misses; + } + break; default: ceph_abort_msg("unknown counter type"); } diff --git a/src/mds/MetricsHandler.cc b/src/mds/MetricsHandler.cc index cfcf3994b8c..156175aca2a 100644 --- a/src/mds/MetricsHandler.cc +++ b/src/mds/MetricsHandler.cc @@ -123,6 +123,7 @@ void MetricsHandler::remove_session(Session *session) { metrics.read_latency_metric = { }; metrics.write_latency_metric = { }; metrics.metadata_latency_metric = { }; + metrics.dentry_lease_metric = { }; metrics.update_type = UPDATE_TYPE_REMOVE; } @@ -196,6 +197,23 @@ void MetricsHandler::handle_payload(Session *session, const MetadataLatencyPaylo metrics.metadata_latency_metric.lat = payload.lat; } +void MetricsHandler::handle_payload(Session *session, const DentryLeasePayload &payload) { + dout(20) << ": type=" << static_cast(DentryLeasePayload::METRIC_TYPE) + << ", session=" << session << ", hits=" << payload.dlease_hits << ", misses=" + << payload.dlease_misses << dendl; + + auto it = client_metrics_map.find(session->info.inst); + if (it == client_metrics_map.end()) { + return; + } + + auto &metrics = it->second.second; + metrics.update_type = UPDATE_TYPE_REFRESH; + metrics.dentry_lease_metric.hits = payload.dlease_hits; + metrics.dentry_lease_metric.misses = payload.dlease_misses; + metrics.dentry_lease_metric.updated = true; +} + void MetricsHandler::handle_payload(Session *session, const UnknownPayload &payload) { dout(5) << ": session=" << session << ", ignoring unknown payload" << dendl; } diff --git a/src/mds/MetricsHandler.h b/src/mds/MetricsHandler.h index 2770ce229d3..e03c2c43104 100644 --- a/src/mds/MetricsHandler.h +++ b/src/mds/MetricsHandler.h @@ -94,6 +94,7 @@ private: void handle_payload(Session *session, const ReadLatencyPayload &payload); void handle_payload(Session *session, const WriteLatencyPayload &payload); void handle_payload(Session *session, const MetadataLatencyPayload &payload); + void handle_payload(Session *session, const DentryLeasePayload &payload); void handle_payload(Session *session, const UnknownPayload &payload); void set_next_seq(version_t seq); diff --git a/src/mds/cephfs_features.h b/src/mds/cephfs_features.h index a8610e99e41..c959e281f83 100644 --- a/src/mds/cephfs_features.h +++ b/src/mds/cephfs_features.h @@ -65,6 +65,7 @@ namespace ceph { CLIENT_METRIC_TYPE_READ_LATENCY, \ CLIENT_METRIC_TYPE_WRITE_LATENCY, \ CLIENT_METRIC_TYPE_METADATA_LATENCY, \ + CLIENT_METRIC_TYPE_DENTRY_LEASE, \ } #define CEPHFS_FEATURES_MDS_SUPPORTED CEPHFS_FEATURES_ALL diff --git a/src/mgr/BaseMgrModule.cc b/src/mgr/BaseMgrModule.cc index 4fa592492a7..49b5f5627c1 100644 --- a/src/mgr/BaseMgrModule.cc +++ b/src/mgr/BaseMgrModule.cc @@ -1047,6 +1047,7 @@ ceph_add_mds_perf_query(BaseMgrModule *self, PyObject *args) {"read_latency", MDSPerformanceCounterType::READ_LATENCY_METRIC}, {"write_latency", MDSPerformanceCounterType::WRITE_LATENCY_METRIC}, {"metadata_latency", MDSPerformanceCounterType::METADATA_LATENCY_METRIC}, + {"dentry_lease", MDSPerformanceCounterType::DENTRY_LEASE_METRIC}, }; PyObject *py_query = nullptr; diff --git a/src/mgr/MDSPerfMetricTypes.cc b/src/mgr/MDSPerfMetricTypes.cc index 5af885b4792..08279928405 100644 --- a/src/mgr/MDSPerfMetricTypes.cc +++ b/src/mgr/MDSPerfMetricTypes.cc @@ -29,6 +29,7 @@ void MDSPerformanceCounterDescriptor::pack_counter( case MDSPerformanceCounterType::READ_LATENCY_METRIC: case MDSPerformanceCounterType::WRITE_LATENCY_METRIC: case MDSPerformanceCounterType::METADATA_LATENCY_METRIC: + case MDSPerformanceCounterType::DENTRY_LEASE_METRIC: break; default: ceph_abort_msg("unknown counter type"); @@ -45,6 +46,7 @@ void MDSPerformanceCounterDescriptor::unpack_counter( case MDSPerformanceCounterType::READ_LATENCY_METRIC: case MDSPerformanceCounterType::WRITE_LATENCY_METRIC: case MDSPerformanceCounterType::METADATA_LATENCY_METRIC: + case MDSPerformanceCounterType::DENTRY_LEASE_METRIC: break; default: ceph_abort_msg("unknown counter type"); @@ -65,6 +67,9 @@ std::ostream& operator<<(std::ostream &os, const MDSPerformanceCounterDescriptor case MDSPerformanceCounterType::METADATA_LATENCY_METRIC: os << "metadata_latency_metric"; break; + case MDSPerformanceCounterType::DENTRY_LEASE_METRIC: + os << "dentry_lease_metric"; + break; } return os; diff --git a/src/mgr/MDSPerfMetricTypes.h b/src/mgr/MDSPerfMetricTypes.h index 1568d9c68c4..9a5feb5e839 100644 --- a/src/mgr/MDSPerfMetricTypes.h +++ b/src/mgr/MDSPerfMetricTypes.h @@ -120,6 +120,7 @@ enum class MDSPerformanceCounterType : uint8_t { READ_LATENCY_METRIC = 1, WRITE_LATENCY_METRIC = 2, METADATA_LATENCY_METRIC = 3, + DENTRY_LEASE_METRIC = 4, }; struct MDSPerformanceCounterDescriptor { @@ -131,6 +132,7 @@ struct MDSPerformanceCounterDescriptor { case MDSPerformanceCounterType::READ_LATENCY_METRIC: case MDSPerformanceCounterType::WRITE_LATENCY_METRIC: case MDSPerformanceCounterType::METADATA_LATENCY_METRIC: + case MDSPerformanceCounterType::DENTRY_LEASE_METRIC: return true; default: return false; diff --git a/src/pybind/mgr/stats/fs/perf_stats.py b/src/pybind/mgr/stats/fs/perf_stats.py index a70e5f708a9..a84c9ad7ac8 100644 --- a/src/pybind/mgr/stats/fs/perf_stats.py +++ b/src/pybind/mgr/stats/fs/perf_stats.py @@ -27,9 +27,10 @@ MDS_PERF_QUERY_REGEX_MATCH_CLIENTS = '^(client.{0}\s+{1}):.*' MDS_PERF_QUERY_COUNTERS_MAP = OrderedDict({'cap_hit': 0, 'read_latency': 1, 'write_latency': 2, - 'metadata_latency': 3}) + 'metadata_latency': 3, + 'dentry_lease': 4}) MDS_PERF_QUERY_COUNTERS = [] # type: List[str] -MDS_GLOBAL_PERF_QUERY_COUNTERS = ['cap_hit', 'read_latency', 'write_latency', 'metadata_latency'] # type: List[str] +MDS_GLOBAL_PERF_QUERY_COUNTERS = ['cap_hit', 'read_latency', 'write_latency', 'metadata_latency', 'dentry_lease'] # type: List[str] QUERY_EXPIRE_INTERVAL = timedelta(minutes=1)