Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add overhead of all DBs and rehashing dict count to info. #12913

Merged
merged 30 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
828d9c5
Add db overhead and rehashing dict count to info.
CharlesChen888 Jan 5, 2024
49701d3
Remove part of the test.
CharlesChen888 Jan 5, 2024
577fae0
Change to show ht0 and ht1.
CharlesChen888 Jan 24, 2024
b94bb8e
Skip in external server tests.
CharlesChen888 Jan 24, 2024
388ec76
Change metric.
CharlesChen888 Jan 24, 2024
3883112
Change metric's name.
CharlesChen888 Jan 25, 2024
c02cd25
Update tests.
CharlesChen888 Jan 25, 2024
941b0cc
Clear hashtable overhead when dict is cleared.
CharlesChen888 Jan 26, 2024
9adba36
Dedict ht0 from metric when clearin…
CharlesChen888 Jan 29, 2024
54e0443
Simplify clearHashtableOverhead.
CharlesChen888 Jan 29, 2024
9f29d61
Merge branch 'unstable' into add-db-meta-data-to-info
CharlesChen888 Feb 19, 2024
397bcf9
Maintain rehashing overhead info inside kvstore.
CharlesChen888 Feb 19, 2024
6269232
Remove unecessary include. Calculate memory inside kvstore. Count ove…
CharlesChen888 Feb 20, 2024
6936a6f
Merge branch 'unstable' into add-db-meta-data-to-info
CharlesChen888 Feb 21, 2024
37921b8
Fix reply map len. Add metric to memory stats.
CharlesChen888 Feb 21, 2024
1ff269b
Remove unnecessary calculation.
CharlesChen888 Feb 21, 2024
f3dc2d1
Modify reply schema.
CharlesChen888 Feb 21, 2024
dfe61be
Change metirc name to avoid reply schema linter check.
CharlesChen888 Feb 21, 2024
fd1d3a4
Modify metric name in test.
CharlesChen888 Feb 21, 2024
d78c41f
Remove unnecessary return. Make test more robust.
CharlesChen888 Feb 22, 2024
98d8a78
Optimize test "Redis can resize empty dict".
CharlesChen888 Feb 22, 2024
a73ae1c
Remove unnecessary adding key.
CharlesChen888 Feb 22, 2024
d6a0c87
Add prefix to metirc name to prevent misunderstanding.
CharlesChen888 Feb 23, 2024
f5efa23
Optimize memory stats display.
CharlesChen888 Feb 23, 2024
628c7db
Revert "Optimize memory stats display."
CharlesChen888 Feb 27, 2024
62f3dfe
Optimize memory stats display using bucket count.
CharlesChen888 Feb 27, 2024
3a2680e
Clear metrics in kvstoreEmpty.
CharlesChen888 Feb 27, 2024
8112d56
Memory stats display only dbs with allocated dicts.
CharlesChen888 Feb 29, 2024
d3d6f2c
Rename everything again.
CharlesChen888 Feb 29, 2024
daa580a
Merge branch 'unstable' into add-db-meta-data-to-info
CharlesChen888 Feb 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/commands/memory-stats.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,18 @@
"functions.caches": {
"type": "integer"
},
"overhead.hashtable.lut": {
"type": "integer"
},
"overhead.hashtable.rehashing": {
"type": "integer"
},
"overhead.total": {
"type": "integer"
},
"dict.rehashing.count": {
soloestoy marked this conversation as resolved.
Show resolved Hide resolved
"type": "integer"
},
"keys.count": {
"type": "integer"
},
Expand Down
24 changes: 20 additions & 4 deletions src/kvstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ struct _kvstore {
unsigned long long key_count; /* Total number of keys in this kvstore. */
unsigned long long bucket_count; /* Total number of buckets in this kvstore across dictionaries. */
unsigned long long *dict_size_index; /* Binary indexed tree (BIT) that describes cumulative key frequencies up until given dict-index. */
size_t overhead_hashtable_lut; /* The overhead of all dictionaries. */
soloestoy marked this conversation as resolved.
Show resolved Hide resolved
size_t overhead_hashtable_rehashing; /* The overhead of dictionaries rehashing. */
};

/* Structure for kvstore iterator that allows iterating across multiple dicts. */
Expand Down Expand Up @@ -191,11 +193,11 @@ static void kvstoreDictRehashingStarted(dict *d) {
listAddNodeTail(kvs->rehashing, d);
metadata->rehashing_node = listLast(kvs->rehashing);

if (kvs->num_dicts == 1)
return;
unsigned long long from, to;
dictRehashingInfo(d, &from, &to);
kvs->bucket_count += to; /* Started rehashing (Add the new ht size) */
kvs->overhead_hashtable_lut += to;
kvs->overhead_hashtable_rehashing += from;
}

/* Remove dictionary from the rehashing list.
Expand All @@ -210,11 +212,11 @@ static void kvstoreDictRehashingCompleted(dict *d) {
metadata->rehashing_node = NULL;
}

if (kvs->num_dicts == 1)
return;
unsigned long long from, to;
dictRehashingInfo(d, &from, &to);
kvs->bucket_count -= from; /* Finished rehashing (Remove the old ht size) */
kvs->overhead_hashtable_lut -= from;
kvs->overhead_hashtable_rehashing -= from;
}

/* Returns the size of the DB dict metadata in bytes. */
Expand Down Expand Up @@ -264,6 +266,8 @@ kvstore *kvstoreCreate(dictType *type, int num_dicts_bits, int flags) {
kvs->resize_cursor = 0;
kvs->dict_size_index = kvs->num_dicts > 1? zcalloc(sizeof(unsigned long long) * (kvs->num_dicts + 1)) : NULL;
kvs->bucket_count = 0;
kvs->overhead_hashtable_lut = 0;
kvs->overhead_hashtable_rehashing = 0;

return kvs;
}
Expand Down Expand Up @@ -628,6 +632,18 @@ uint64_t kvstoreIncrementallyRehash(kvstore *kvs, uint64_t threshold_us) {
return elapsed_us;
}

size_t kvstoreOverheadHashtableLut(kvstore *kvs) {
return kvs->overhead_hashtable_lut * sizeof(dictEntry *);
}

size_t kvstoreOverheadHashtableRehashing(kvstore *kvs) {
return kvs->overhead_hashtable_rehashing * sizeof(dictEntry *);
}

unsigned long kvstoreDictRehashingCount(kvstore *kvs) {
return listLength(kvs->rehashing);
}

unsigned long kvstoreDictSize(kvstore *kvs, int didx)
{
dict *d = kvstoreGetDict(kvs, didx);
Expand Down
3 changes: 3 additions & 0 deletions src/kvstore.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ dictEntry *kvstoreIteratorNext(kvstoreIterator *kvs_it);
/* Rehashing */
void kvstoreTryResizeDicts(kvstore *kvs, int limit);
uint64_t kvstoreIncrementallyRehash(kvstore *kvs, uint64_t threshold_us);
size_t kvstoreOverheadHashtableLut(kvstore *kvs);
size_t kvstoreOverheadHashtableRehashing(kvstore *kvs);
unsigned long kvstoreDictRehashingCount(kvstore *kvs);

/* Specific dict access by dict-index */
unsigned long kvstoreDictSize(kvstore *kvs, int didx);
Expand Down
19 changes: 17 additions & 2 deletions src/object.c
oranagra marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -1247,7 +1247,6 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
for (j = 0; j < server.dbnum; j++) {
redisDb *db = server.db+j;
unsigned long long keyscount = kvstoreSize(db->keys);
if (keyscount == 0) continue;
soloestoy marked this conversation as resolved.
Show resolved Hide resolved

mh->total_keys += keyscount;
mh->db = zrealloc(mh->db,sizeof(mh->db[0])*(mh->num_dbs+1));
Expand All @@ -1263,6 +1262,13 @@ struct redisMemOverhead *getMemoryOverheadData(void) {
mem_total+=mem;

mh->num_dbs++;

mh->db_overhead_hashtable_lut += kvstoreOverheadHashtableLut(db->keys);
soloestoy marked this conversation as resolved.
Show resolved Hide resolved
mh->db_overhead_hashtable_lut += kvstoreOverheadHashtableLut(db->expires);
soloestoy marked this conversation as resolved.
Show resolved Hide resolved
mh->db_overhead_hashtable_rehashing += kvstoreOverheadHashtableRehashing(db->keys);
mh->db_overhead_hashtable_rehashing += kvstoreOverheadHashtableRehashing(db->expires);
mh->db_dict_rehashing_count += kvstoreDictRehashingCount(db->keys);
mh->db_dict_rehashing_count += kvstoreDictRehashingCount(db->expires);
}

mh->overhead_total = mem_total;
Expand Down Expand Up @@ -1556,7 +1562,7 @@ NULL
} else if (!strcasecmp(c->argv[1]->ptr,"stats") && c->argc == 2) {
struct redisMemOverhead *mh = getMemoryOverheadData();

addReplyMapLen(c,28+mh->num_dbs);
addReplyMapLen(c,31+mh->num_dbs);

addReplyBulkCString(c,"peak.allocated");
addReplyLongLong(c,mh->peak_allocated);
Expand Down Expand Up @@ -1601,9 +1607,18 @@ NULL
addReplyLongLong(c,mh->db[j].overhead_ht_expires);
}

addReplyBulkCString(c,"overhead.hashtable.lut");
addReplyLongLong(c, mh->db_overhead_hashtable_lut);

addReplyBulkCString(c,"overhead.hashtable.rehashing");
addReplyLongLong(c, mh->db_overhead_hashtable_rehashing);

addReplyBulkCString(c,"overhead.total");
addReplyLongLong(c,mh->overhead_total);

addReplyBulkCString(c,"dict.rehashing.count");
soloestoy marked this conversation as resolved.
Show resolved Hide resolved
addReplyLongLong(c, mh->db_dict_rehashing_count);

addReplyBulkCString(c,"keys.count");
addReplyLongLong(c,mh->total_keys);

Expand Down
1 change: 1 addition & 0 deletions src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -5685,6 +5685,7 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) {
"mem_cluster_links:%zu\r\n", mh->cluster_links,
"mem_aof_buffer:%zu\r\n", mh->aof_buffer,
"mem_allocator:%s\r\n", ZMALLOC_LIB,
"mem_overhead_hashtable_rehashing:%zu\r\n", mh->db_overhead_hashtable_rehashing,
"active_defrag_running:%d\r\n", server.active_defrag_running,
"lazyfree_pending_objects:%zu\r\n", lazyfreeGetPendingObjectsCount(),
"lazyfreed_objects:%zu\r\n", lazyfreeGetFreedObjectsCount()));
Expand Down
3 changes: 3 additions & 0 deletions src/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,9 @@ struct redisMemOverhead {
float rss_extra;
size_t rss_extra_bytes;
size_t num_dbs;
size_t db_overhead_hashtable_lut;
size_t db_overhead_hashtable_rehashing;
unsigned long db_dict_rehashing_count;
struct {
size_t dbid;
enjoy-binbin marked this conversation as resolved.
Show resolved Hide resolved
size_t overhead_ht_main;
Expand Down
36 changes: 36 additions & 0 deletions tests/unit/info.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -465,3 +465,39 @@ start_server {tags {"info" "external:skip"}} {
}
}
}

start_server {tags {"info" "external:skip"}} {
test {memory: database and pubsub overhead and rehashing dict count} {
r flushall
set info_mem [r info memory]
set mem_stats [r memory stats]
assert_equal [getInfoProperty $info_mem mem_overhead_hashtable_rehashing] {0}
assert_equal [dict get $mem_stats overhead.hashtable.lut] {0}
assert_equal [dict get $mem_stats overhead.hashtable.rehashing] {0}
assert_equal [dict get $mem_stats dict.rehashing.count] {0}
# Initial dict expand is not rehashing
r set a b
set info_mem [r info memory]
set mem_stats [r memory stats]
assert_equal [getInfoProperty $info_mem mem_overhead_hashtable_rehashing] {0}
assert_range [dict get $mem_stats overhead.hashtable.lut] 1 64
assert_equal [dict get $mem_stats overhead.hashtable.rehashing] {0}
assert_equal [dict get $mem_stats dict.rehashing.count] {0}
# set 4 more keys to trigger rehashing
# get the info within a transaction to make sure the rehashing is not completed
r multi
r set b c
r set c d
r set d e
r set e f
r info memory
r memory stats
set res [r exec]
enjoy-binbin marked this conversation as resolved.
Show resolved Hide resolved
set info_mem [lindex $res 4]
set mem_stats [lindex $res 5]
assert_range [getInfoProperty $info_mem mem_overhead_hashtable_rehashing] 1 64
assert_range [dict get $mem_stats overhead.hashtable.lut] 1 192
assert_range [dict get $mem_stats overhead.hashtable.rehashing] 1 64
assert_equal [dict get $mem_stats dict.rehashing.count] {1}
}
}
17 changes: 1 addition & 16 deletions tests/unit/other.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -489,19 +489,6 @@ start_cluster 1 0 {tags {"other external:skip cluster slow"}} {
} {} {needs:debug}
}

proc get_overhead_hashtable_main {} {
set main 0
set stats [r memory stats]
set list_stats [split $stats " "]
for {set j 0} {$j < [llength $list_stats]} {incr j} {
if {[string equal -nocase "\{overhead.hashtable.main" [lindex $list_stats $j]]} {
set main [lindex $list_stats [expr $j+1]]
break
}
}
return $main
}

start_server {tags {"other external:skip"}} {
test "Redis can resize empty dict" {
# Write and then delete 128 keys, creating an empty dict
Expand All @@ -512,12 +499,10 @@ start_server {tags {"other external:skip"}} {
for {set j 1} {$j <= 128} {incr j} {
r del $j{b}
}
# Set a key to enable overhead display of db 0
r set a b
# The dict containing 128 keys must have expanded,
# its hash table itself takes a lot more than 400 bytes
wait_for_condition 100 50 {
[get_overhead_hashtable_main] < 400
[dict get [r memory stats] db.9 overhead.hashtable.main] < 400
} else {
fail "dict did not resize in time"
}
Expand Down
Loading