Skip to content

Commit 384f7ea

Browse files
authored
feat: add KEY dimenstion for memory usage (#6043)
Before: key memory and string memory were reported as one. Now: metrics and info memory will have a separate dimension for keys using heap memory. Signed-off-by: Roman Gershman <[email protected]>
1 parent b28369e commit 384f7ea

File tree

7 files changed

+27
-17
lines changed

7 files changed

+27
-17
lines changed

src/core/compact_object.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,10 +1660,12 @@ bool CompactObj::JsonWrapper::DefragIfNeeded(PageUsage* page_usage) {
16601660
return flat.DefragIfNeeded(page_usage);
16611661
}
16621662

1663-
constexpr std::pair<CompactObjType, std::string_view> kObjTypeToString[8] = {
1664-
{OBJ_STRING, "string"sv}, {OBJ_LIST, "list"sv}, {OBJ_SET, "set"sv},
1665-
{OBJ_ZSET, "zset"sv}, {OBJ_HASH, "hash"sv}, {OBJ_STREAM, "stream"sv},
1666-
{OBJ_JSON, "ReJSON-RL"sv}, {OBJ_SBF, "MBbloom--"sv}};
1663+
constexpr std::pair<CompactObjType, std::string_view> kObjTypeToString[] =
1664+
{
1665+
{OBJ_STRING, "string"sv}, {OBJ_LIST, "list"sv}, {OBJ_SET, "set"sv},
1666+
{OBJ_ZSET, "zset"sv}, {OBJ_HASH, "hash"sv}, {OBJ_STREAM, "stream"sv},
1667+
{OBJ_KEY, "key"sv}, // pseudo-type used for memory tracking
1668+
{OBJ_JSON, "ReJSON-RL"sv}, {OBJ_SBF, "MBbloom--"sv}};
16671669

16681670
std::string_view ObjTypeToString(CompactObjType type) {
16691671
for (auto& p : kObjTypeToString) {

src/redis/redis_aux.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#define OBJ_JSON 15U
1010
#define OBJ_SBF 16U
1111

12+
// A pseudo type for keys stored in the db, same as OBJ_MODULE which is not used in Dragonfly.
13+
#define OBJ_KEY 5U
14+
1215
/* How many types of objects exist */
1316
#define OBJ_TYPE_MAX 17U
1417

src/server/db_slice.cc

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,9 @@ DbSlice::AutoUpdater::~AutoUpdater() {
483483
}
484484

485485
void DbSlice::AutoUpdater::ReduceHeapUsage() {
486-
AccountObjectMemory(fields_.key, fields_.it->second.ObjType(), -fields_.orig_heap_size,
486+
AccountObjectMemory(fields_.key, fields_.it->second.ObjType(), -fields_.orig_value_heap_size,
487487
fields_.db_slice->GetDBTable(fields_.db_ind));
488-
fields_.orig_heap_size = 0; // Reset to avoid double accounting.
488+
fields_.orig_value_heap_size = 0; // Reset to avoid double accounting.
489489
}
490490

491491
void DbSlice::AutoUpdater::Run() {
@@ -501,7 +501,7 @@ void DbSlice::AutoUpdater::Run() {
501501
CHECK_NE(fields_.db_slice, nullptr);
502502

503503
ssize_t delta = static_cast<int64_t>(fields_.it->second.MallocUsed()) -
504-
static_cast<int64_t>(fields_.orig_heap_size);
504+
static_cast<int64_t>(fields_.orig_value_heap_size);
505505
AccountObjectMemory(fields_.key, fields_.it->second.ObjType(), delta,
506506
fields_.db_slice->GetDBTable(fields_.db_ind));
507507
fields_.db_slice->PostUpdate(fields_.db_ind, fields_.key);
@@ -518,7 +518,7 @@ DbSlice::AutoUpdater::AutoUpdater(DbIndex db_ind, std::string_view key, const It
518518
.db_ind = db_ind,
519519
.it = it,
520520
.key = key,
521-
.orig_heap_size = it->second.MallocUsed()} {
521+
.orig_value_heap_size = it->second.MallocUsed()} {
522522
DCHECK(IsValid(it));
523523
}
524524

@@ -770,7 +770,7 @@ OpResult<DbSlice::ItAndUpdater> DbSlice::AddOrFindInternal(const Context& cntx,
770770
if (it->first.IsInline()) {
771771
++db.stats.inline_keys;
772772
} else {
773-
AccountObjectMemory(key, it->first.ObjType(), it->first.MallocUsed(), &db); // Account for key
773+
AccountObjectMemory(key, OBJ_KEY, it->first.MallocUsed(), &db); // Account for key
774774
}
775775

776776
DCHECK_EQ(it->second.MallocUsed(), 0UL); // Make sure accounting is no-op
@@ -1553,7 +1553,7 @@ void DbSlice::InvalidateSlotWatches(const cluster::SlotSet& slot_ids) {
15531553
}
15541554

15551555
void DbSlice::RemoveOffloadedEntriesFromTieredStorage(absl::Span<const DbIndex> indices,
1556-
const DbTableArray& db_arr) {
1556+
const DbTableArray& db_arr) const {
15571557
// Currently being used only for tiered storage.
15581558
TieredStorage* tiered_storage = shard_owner()->tiered_storage();
15591559
string scratch;
@@ -1787,8 +1787,7 @@ void DbSlice::PerformDeletionAtomic(const Iterator& del_it, const ExpIterator& e
17871787
if (del_it->first.IsInline()) {
17881788
--stats.inline_keys;
17891789
} else {
1790-
AccountObjectMemory(del_it.key(), del_it->first.ObjType(), -key_size_used,
1791-
table); // Key
1790+
AccountObjectMemory(del_it.key(), OBJ_KEY, -key_size_used, table); // Key
17921791
}
17931792
AccountObjectMemory(del_it.key(), pv.ObjType(), -value_heap_size, table); // Value
17941793

src/server/db_slice.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ class DbSlice {
174174
std::string_view key;
175175

176176
// The following fields are calculated at init time
177-
size_t orig_heap_size = 0;
177+
size_t orig_value_heap_size = 0;
178178
};
179179

180180
AutoUpdater(DbIndex db_ind, std::string_view key, const Iterator& it, DbSlice* db_slice);
@@ -570,7 +570,7 @@ class DbSlice {
570570

571571
// Clear tiered storage entries for the specified indices. Called during flushing some indices.
572572
void RemoveOffloadedEntriesFromTieredStorage(absl::Span<const DbIndex> indices,
573-
const DbTableArray& db_arr);
573+
const DbTableArray& db_arr) const;
574574

575575
void PerformDeletionAtomic(const Iterator& del_it, const ExpIterator& exp_it, DbTable* table);
576576

src/server/dragonfly_test.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,12 @@ TEST_F(DflyEngineTest, Huffman) {
953953
EXPECT_LT(metrics.heap_used_bytes, 14'000'000); // less than 15mb
954954
}
955955

956+
TEST_F(DflyEngineTest, MemoryKeys) {
957+
Run({"debug", "populate", "10000", "abcd_efgh_ijkl_mnop", "10"});
958+
auto metrics = GetMetrics();
959+
EXPECT_GT(metrics.db_stats[0].memory_usage_by_type[OBJ_KEY], 100000);
960+
}
961+
956962
class DflyCommandAliasTest : public DflyEngineTest {
957963
protected:
958964
DflyCommandAliasTest() {

src/server/engine_shard.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ void EngineShard::Shutdown() {
346346
}
347347

348348
void EngineShard::StopPeriodicFiber() {
349-
ProactorBase::me()->RemoveOnIdleTask(defrag_task_);
349+
ProactorBase::me()->RemoveOnIdleTask(defrag_task_id_);
350350
fiber_heartbeat_periodic_done_.Notify();
351351
if (fiber_heartbeat_periodic_.IsJoinable()) {
352352
fiber_heartbeat_periodic_.Join();
@@ -393,7 +393,7 @@ void EngineShard::StartPeriodicHeartbeatFiber(util::ProactorBase* pb) {
393393
fiber_heartbeat_periodic_ = fb2::Fiber(fb_opts, [this, period_ms, heartbeat]() mutable {
394394
RunFPeriodically(heartbeat, period_ms, "heartbeat", &fiber_heartbeat_periodic_done_);
395395
});
396-
defrag_task_ = pb->AddOnIdleTask([this]() { return DefragTask(); });
396+
defrag_task_id_ = pb->AddOnIdleTask([this]() { return DefragTask(); });
397397
}
398398

399399
void EngineShard::StartPeriodicShardHandlerFiber(util::ProactorBase* pb,

src/server/engine_shard.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ class EngineShard {
294294
journal::Journal* journal_ = nullptr;
295295
IntentLock shard_lock_;
296296

297-
uint32_t defrag_task_ = 0;
297+
uint32_t defrag_task_id_ = 0;
298298
EvictionTaskState eviction_state_; // Used on eviction fiber
299299
util::fb2::Fiber fiber_heartbeat_periodic_;
300300
util::fb2::Done fiber_heartbeat_periodic_done_;

0 commit comments

Comments
 (0)