summaryrefslogtreecommitdiffstats
path: root/storage
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@verizonmedia.com>2020-09-04 15:30:24 +0000
committerTor Brede Vekterli <vekterli@verizonmedia.com>2020-09-04 15:30:24 +0000
commitca28ce90eaf1c4f247ce70533bb5937bce8755a6 (patch)
tree8a123af830b100a8c69aefa8663728f8b28dba0f /storage
parentc741567b8ff65815ee8ab470032a079f7f2d2e43 (diff)
Add content node bucket DB memory usage metrics
Diffstat (limited to 'storage')
-rw-r--r--storage/src/tests/bucketdb/bucketmanagertest.cpp20
-rw-r--r--storage/src/vespa/storage/bucketdb/abstract_bucket_map.h2
-rw-r--r--storage/src/vespa/storage/bucketdb/btree_lockable_map.h1
-rw-r--r--storage/src/vespa/storage/bucketdb/btree_lockable_map.hpp6
-rw-r--r--storage/src/vespa/storage/bucketdb/bucketmanager.cpp9
-rw-r--r--storage/src/vespa/storage/bucketdb/bucketmanager.h1
-rw-r--r--storage/src/vespa/storage/bucketdb/bucketmanagermetrics.cpp10
-rw-r--r--storage/src/vespa/storage/bucketdb/bucketmanagermetrics.h9
-rw-r--r--storage/src/vespa/storage/bucketdb/lockablemap.h1
-rw-r--r--storage/src/vespa/storage/bucketdb/lockablemap.hpp9
-rw-r--r--storage/src/vespa/storage/bucketdb/storbucketdb.cpp4
-rw-r--r--storage/src/vespa/storage/bucketdb/storbucketdb.h4
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;
};