diff options
author | Tor Brede Vekterli <vekterli@verizonmedia.com> | 2020-09-04 15:30:24 +0000 |
---|---|---|
committer | Tor Brede Vekterli <vekterli@verizonmedia.com> | 2020-09-04 15:30:24 +0000 |
commit | ca28ce90eaf1c4f247ce70533bb5937bce8755a6 (patch) | |
tree | 8a123af830b100a8c69aefa8663728f8b28dba0f /storage | |
parent | c741567b8ff65815ee8ab470032a079f7f2d2e43 (diff) |
Add content node bucket DB memory usage metrics
Diffstat (limited to 'storage')
12 files changed, 73 insertions, 3 deletions
diff --git a/storage/src/tests/bucketdb/bucketmanagertest.cpp b/storage/src/tests/bucketdb/bucketmanagertest.cpp index 123dc401b5a..678e3aa621c 100644 --- a/storage/src/tests/bucketdb/bucketmanagertest.cpp +++ b/storage/src/tests/bucketdb/bucketmanagertest.cpp @@ -289,7 +289,7 @@ TEST_F(BucketManagerTest, distribution_bit_change_on_create_bucket){ EXPECT_EQ(4u, _node->getStateUpdater().getReportedNodeState()->getMinUsedBits()); } -TEST_F(BucketManagerTest, Min_Used_Bits_From_Component_Is_Honored) { +TEST_F(BucketManagerTest, min_used_bits_from_component_is_honored) { setupTestEnvironment(); // Let these differ in order to test state update behavior. _node->getComponentRegister().getMinUsedBitsTracker().setMinUsedBits(10); @@ -464,6 +464,20 @@ TEST_F(BucketManagerTest, metrics_generation) { EXPECT_EQ(2, m.ready.getLast()); } +namespace { + +void verify_db_memory_metrics_present(const ContentBucketDbMetrics& db_metrics) { + auto* m = db_metrics.memory_usage.getMetric("allocated_bytes"); + ASSERT_TRUE(m != nullptr); + // Actual values are very much implementation defined, so just check for non-zero. + EXPECT_GT(m->getLongValue("last"), 0); + m = db_metrics.memory_usage.getMetric("used_bytes"); + ASSERT_TRUE(m != nullptr); + EXPECT_GT(m->getLongValue("last"), 0); +} + +} + TEST_F(BucketManagerTest, metrics_are_tracked_per_bucket_space) { setupTestEnvironment(); _top->open(); @@ -499,6 +513,8 @@ TEST_F(BucketManagerTest, metrics_are_tracked_per_bucket_space) { EXPECT_EQ(0, default_m->second->active_buckets.getLast()); EXPECT_EQ(1, default_m->second->ready_buckets.getLast()); + verify_db_memory_metrics_present(default_m->second->bucket_db_metrics); + auto global_m = spaces.find(document::FixedBucketSpaces::global_space()); ASSERT_TRUE(global_m != spaces.end()); EXPECT_EQ(1, global_m->second->buckets_total.getLast()); @@ -506,6 +522,8 @@ TEST_F(BucketManagerTest, metrics_are_tracked_per_bucket_space) { EXPECT_EQ(300, global_m->second->bytes.getLast()); EXPECT_EQ(1, global_m->second->active_buckets.getLast()); EXPECT_EQ(0, global_m->second->ready_buckets.getLast()); + + verify_db_memory_metrics_present(global_m->second->bucket_db_metrics); } void diff --git a/storage/src/vespa/storage/bucketdb/abstract_bucket_map.h b/storage/src/vespa/storage/bucketdb/abstract_bucket_map.h index ae4c48ed22f..9b738b26994 100644 --- a/storage/src/vespa/storage/bucketdb/abstract_bucket_map.h +++ b/storage/src/vespa/storage/bucketdb/abstract_bucket_map.h @@ -5,6 +5,7 @@ #include <vespa/document/bucket/bucketid.h> #include <vespa/vespalib/stllike/hash_map.h> #include <vespa/vespalib/stllike/hash_set.h> +#include <vespa/vespalib/util/memoryusage.h> #include <vespa/vespalib/util/time.h> #include <cassert> #include <functional> @@ -192,6 +193,7 @@ public: [[nodiscard]] virtual size_type size() const noexcept = 0; [[nodiscard]] virtual size_type getMemoryUsage() const noexcept = 0; + [[nodiscard]] virtual vespalib::MemoryUsage detailed_memory_usage() const noexcept = 0; [[nodiscard]] virtual bool empty() const noexcept = 0; virtual void showLockClients(vespalib::asciistream& out) const = 0; diff --git a/storage/src/vespa/storage/bucketdb/btree_lockable_map.h b/storage/src/vespa/storage/bucketdb/btree_lockable_map.h index ba2e6ca28a0..58e4564836b 100644 --- a/storage/src/vespa/storage/bucketdb/btree_lockable_map.h +++ b/storage/src/vespa/storage/bucketdb/btree_lockable_map.h @@ -46,6 +46,7 @@ public: bool operator<(const BTreeLockableMap& other) const; size_t size() const noexcept override; size_t getMemoryUsage() const noexcept override; + vespalib::MemoryUsage detailed_memory_usage() const noexcept override; bool empty() const noexcept override; void swap(BTreeLockableMap&); diff --git a/storage/src/vespa/storage/bucketdb/btree_lockable_map.hpp b/storage/src/vespa/storage/bucketdb/btree_lockable_map.hpp index 69f43e7c3ae..f859897ef11 100644 --- a/storage/src/vespa/storage/bucketdb/btree_lockable_map.hpp +++ b/storage/src/vespa/storage/bucketdb/btree_lockable_map.hpp @@ -150,6 +150,12 @@ size_t BTreeLockableMap<T>::getMemoryUsage() const noexcept { } template <typename T> +vespalib::MemoryUsage BTreeLockableMap<T>::detailed_memory_usage() const noexcept { + std::lock_guard guard(_lock); + return _impl->memory_usage(); +} + +template <typename T> bool BTreeLockableMap<T>::empty() const noexcept { std::lock_guard guard(_lock); return _impl->empty(); diff --git a/storage/src/vespa/storage/bucketdb/bucketmanager.cpp b/storage/src/vespa/storage/bucketdb/bucketmanager.cpp index 530c1236436..9c2d6da39cb 100644 --- a/storage/src/vespa/storage/bucketdb/bucketmanager.cpp +++ b/storage/src/vespa/storage/bucketdb/bucketmanager.cpp @@ -263,6 +263,15 @@ BucketManager::updateMetrics(bool updateDocCount) } } } + update_bucket_db_memory_usage_metrics(); +} + +void BucketManager::update_bucket_db_memory_usage_metrics() { + for (auto& space : _component.getBucketSpaceRepo()) { + auto bm = _metrics->bucket_spaces.find(space.first); + bm->second->bucket_db_metrics.memory_usage.update( + space.second->bucketDatabase().detailed_memory_usage()); + } } void BucketManager::updateMinUsedBits() diff --git a/storage/src/vespa/storage/bucketdb/bucketmanager.h b/storage/src/vespa/storage/bucketdb/bucketmanager.h index 9ba5f770f9d..f234ab2dd77 100644 --- a/storage/src/vespa/storage/bucketdb/bucketmanager.h +++ b/storage/src/vespa/storage/bucketdb/bucketmanager.h @@ -123,6 +123,7 @@ private: void updateMetrics(bool updateDocCount); void updateMetrics(const MetricLockGuard &) override { updateMetrics(true); } + void update_bucket_db_memory_usage_metrics(); void updateMinUsedBits(); bool onRequestBucketInfo(const std::shared_ptr<api::RequestBucketInfoCommand>&) override; diff --git a/storage/src/vespa/storage/bucketdb/bucketmanagermetrics.cpp b/storage/src/vespa/storage/bucketdb/bucketmanagermetrics.cpp index 23acb1f344a..2c1c5379dd9 100644 --- a/storage/src/vespa/storage/bucketdb/bucketmanagermetrics.cpp +++ b/storage/src/vespa/storage/bucketdb/bucketmanagermetrics.cpp @@ -22,13 +22,21 @@ DataStoredMetrics::DataStoredMetrics(const std::string& name, metrics::MetricSet DataStoredMetrics::~DataStoredMetrics() = default; +ContentBucketDbMetrics::ContentBucketDbMetrics(metrics::MetricSet* owner) + : metrics::MetricSet("bucket_db", {}, "", owner), + memory_usage(this) +{} + +ContentBucketDbMetrics::~ContentBucketDbMetrics() = default; + BucketSpaceMetrics::BucketSpaceMetrics(const vespalib::string& space_name, metrics::MetricSet* owner) : metrics::MetricSet("bucket_space", {{"bucketSpace", space_name}}, "", owner), buckets_total("buckets_total", {}, "Total number buckets present in the bucket space (ready + not ready)", this), docs("docs", {}, "Documents stored in the bucket space", this), bytes("bytes", {}, "Bytes stored across all documents in the bucket space", this), active_buckets("active_buckets", {}, "Number of active buckets in the bucket space", this), - ready_buckets("ready_buckets", {}, "Number of ready buckets in the bucket space", this) + ready_buckets("ready_buckets", {}, "Number of ready buckets in the bucket space", this), + bucket_db_metrics(this) {} BucketSpaceMetrics::~BucketSpaceMetrics() = default; diff --git a/storage/src/vespa/storage/bucketdb/bucketmanagermetrics.h b/storage/src/vespa/storage/bucketdb/bucketmanagermetrics.h index 1e7b8960f14..015efbcdc5c 100644 --- a/storage/src/vespa/storage/bucketdb/bucketmanagermetrics.h +++ b/storage/src/vespa/storage/bucketdb/bucketmanagermetrics.h @@ -4,6 +4,7 @@ #include <vespa/document/bucket/bucketspace.h> #include <vespa/metrics/metrics.h> +#include <vespa/metrics/common/memory_usage_metrics.h> #include <unordered_map> #include <memory> @@ -23,6 +24,13 @@ struct DataStoredMetrics : metrics::MetricSet { ~DataStoredMetrics() override; }; +struct ContentBucketDbMetrics : metrics::MetricSet { + explicit ContentBucketDbMetrics(metrics::MetricSet* owner); + ~ContentBucketDbMetrics() override; + + metrics::MemoryUsageMetrics memory_usage; +}; + struct BucketSpaceMetrics : metrics::MetricSet { // Superficially very similar to DataStoredMetrics, but metric naming and dimensions differ metrics::LongValueMetric buckets_total; @@ -30,6 +38,7 @@ struct BucketSpaceMetrics : metrics::MetricSet { metrics::LongValueMetric bytes; metrics::LongValueMetric active_buckets; metrics::LongValueMetric ready_buckets; + ContentBucketDbMetrics bucket_db_metrics; BucketSpaceMetrics(const vespalib::string& space_name, metrics::MetricSet* owner); ~BucketSpaceMetrics() override; diff --git a/storage/src/vespa/storage/bucketdb/lockablemap.h b/storage/src/vespa/storage/bucketdb/lockablemap.h index a79a42b44ab..9584a23d84c 100644 --- a/storage/src/vespa/storage/bucketdb/lockablemap.h +++ b/storage/src/vespa/storage/bucketdb/lockablemap.h @@ -50,6 +50,7 @@ public: bool operator<(const LockableMap& other) const; size_t size() const noexcept override; size_t getMemoryUsage() const noexcept override; + vespalib::MemoryUsage detailed_memory_usage() const noexcept override; bool empty() const noexcept override; void swap(LockableMap&); diff --git a/storage/src/vespa/storage/bucketdb/lockablemap.hpp b/storage/src/vespa/storage/bucketdb/lockablemap.hpp index c475361bd6f..aa62fad5cd0 100644 --- a/storage/src/vespa/storage/bucketdb/lockablemap.hpp +++ b/storage/src/vespa/storage/bucketdb/lockablemap.hpp @@ -85,6 +85,15 @@ LockableMap<Map>::getMemoryUsage() const noexcept sizeof(std::mutex) + sizeof(std::condition_variable); } +template <typename Map> +vespalib::MemoryUsage LockableMap<Map>::detailed_memory_usage() const noexcept { + // We don't have any details for this map type, just count everything as "allocated". + size_t used = getMemoryUsage(); + vespalib::MemoryUsage mem_usage; + mem_usage.incAllocatedBytes(used); + return mem_usage; +} + template<typename Map> bool LockableMap<Map>::empty() const noexcept diff --git a/storage/src/vespa/storage/bucketdb/storbucketdb.cpp b/storage/src/vespa/storage/bucketdb/storbucketdb.cpp index 849164ace7d..e64a19e9a4a 100644 --- a/storage/src/vespa/storage/bucketdb/storbucketdb.cpp +++ b/storage/src/vespa/storage/bucketdb/storbucketdb.cpp @@ -91,6 +91,10 @@ size_t StorBucketDatabase::getMemoryUsage() const { return _impl->getMemoryUsage(); } +vespalib::MemoryUsage StorBucketDatabase::detailed_memory_usage() const noexcept { + return _impl->detailed_memory_usage(); +} + void StorBucketDatabase::showLockClients(vespalib::asciistream& out) const { _impl->showLockClients(out); } diff --git a/storage/src/vespa/storage/bucketdb/storbucketdb.h b/storage/src/vespa/storage/bucketdb/storbucketdb.h index 5aac27bccb0..ff86d7c9afa 100644 --- a/storage/src/vespa/storage/bucketdb/storbucketdb.h +++ b/storage/src/vespa/storage/bucketdb/storbucketdb.h @@ -5,6 +5,7 @@ #include "read_guard.h" #include "storagebucketinfo.h" #include <vespa/storageapi/defs.h> +#include <vespa/vespalib/util/memoryusage.h> #include <memory> namespace storage { @@ -79,7 +80,8 @@ public: */ bool isConsistent(const WrappedEntry& entry); - size_t getMemoryUsage() const; + [[nodiscard]] size_t getMemoryUsage() const; + [[nodiscard]] vespalib::MemoryUsage detailed_memory_usage() const noexcept; void showLockClients(vespalib::asciistream & out) const; }; |