From 34937b0ad5b72807aa53b09a342c3d40cbd6b6bc Mon Sep 17 00:00:00 2001 From: John Sully Date: Sat, 15 Aug 2020 23:05:56 +0000 Subject: [PATCH] Rehash efficiency Former-commit-id: fab383156626ec683881101c22eb2f6c2cea4c5d --- src/db.cpp | 4 ++-- src/dict.cpp | 6 ++++-- src/server.cpp | 11 ++++++----- src/server.h | 2 +- src/snapshot.cpp | 7 ++++++- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index e2a50164c..1cc7e66f7 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -430,7 +430,7 @@ bool redisDbPersistentData::syncDelete(robj *key) auto itr = m_pdbSnapshot->find_cached_threadsafe(szFromObj(key)); if (itr != nullptr) { - sds keyTombstone = sdsdup(szFromObj(key)); + sds keyTombstone = sdsdupshared(itr.key()); uint64_t hash = dictGetHash(m_pdict, keyTombstone); if (dictAdd(m_pdictTombstone, keyTombstone, (void*)hash) != DICT_OK) sdsfree(keyTombstone); @@ -2300,7 +2300,7 @@ void redisDbPersistentData::initialize() { m_pdbSnapshot = nullptr; m_pdict = dictCreate(&dbDictType,this); - m_pdictTombstone = dictCreate(&dbDictTypeTombstone,this); + m_pdictTombstone = dictCreate(&dbTombstoneDictType,this); m_setexpire = new(MALLOC_LOCAL) expireset(); m_fAllChanged = 0; m_fTrackingChanges = 0; diff --git a/src/dict.cpp b/src/dict.cpp index c69c663a4..fda797363 100644 --- a/src/dict.cpp +++ b/src/dict.cpp @@ -326,7 +326,7 @@ int dictRehashMilliseconds(dict *d, int ms) { static void _dictRehashStep(dict *d) { unsigned long iterators; __atomic_load(&d->iterators, &iterators, __ATOMIC_RELAXED); - if (iterators == 0) dictRehash(d,10); + if (iterators == 0) dictRehash(d,2); } /* Add an element to the target hash table */ @@ -1220,7 +1220,9 @@ void dictGetStats(char *buf, size_t bufsize, dict *d) { void dictForceRehash(dict *d) { - while (dictIsRehashing(d)) _dictRehashStep(d); + unsigned long iterators; + __atomic_load(&d->iterators, &iterators, __ATOMIC_RELAXED); + while (iterators == 0 && dictIsRehashing(d)) _dictRehashStep(d); } /* ------------------------------- Benchmark ---------------------------------*/ diff --git a/src/server.cpp b/src/server.cpp index 52648e7bd..f72047c31 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1387,14 +1387,14 @@ dictType dbDictType = { dictObjectDestructor /* val destructor */ }; -/* db->pdict, keys are sds strings, vals uints. */ -dictType dbDictTypeTombstone = { +/* db->pdict, keys are sds strings, vals are Redis objects. */ +dictType dbTombstoneDictType = { dictSdsHash, /* hash function */ NULL, /* key dup */ NULL, /* val dup */ dictSdsKeyCompare, /* key compare */ - dictDbKeyDestructor, /* key destructor */ - NULL /* val destructor */ + dictDbKeyDestructor, /* key destructor */ + NULL /* val destructor */ }; dictType dbSnapshotDictType = { @@ -1539,8 +1539,9 @@ void tryResizeHashTables(int dbid) { * is returned. */ int redisDbPersistentData::incrementallyRehash() { /* Keys dictionary */ - if (dictIsRehashing(m_pdict)) { + if (dictIsRehashing(m_pdict) || dictIsRehashing(m_pdictTombstone)) { dictRehashMilliseconds(m_pdict,1); + dictRehashMilliseconds(m_pdictTombstone,1); return 1; /* already used our millisecond for this loop... */ } return 0; diff --git a/src/server.h b/src/server.h index 4f9375834..ce521b2b6 100644 --- a/src/server.h +++ b/src/server.h @@ -2564,7 +2564,7 @@ extern dictType zsetDictType; extern dictType clusterNodesDictType; extern dictType clusterNodesBlackListDictType; extern dictType dbDictType; -extern dictType dbDictTypeTombstone; +extern dictType dbTombstoneDictType; extern dictType dbSnapshotDictType; extern dictType shaScriptObjectDictType; extern double R_Zero, R_PosInf, R_NegInf, R_Nan; diff --git a/src/snapshot.cpp b/src/snapshot.cpp index 8dd4db367..bd476be26 100644 --- a/src/snapshot.cpp +++ b/src/snapshot.cpp @@ -91,8 +91,13 @@ const redisDbPersistentDataSnapshot *redisDbPersistentData::createSnapshot(uint6 spdb->m_setexpire->pause_rehash(); // needs to be const } + if (dictIsRehashing(spdb->m_pdict) || dictIsRehashing(spdb->m_pdictTombstone)) { + serverLog(LL_NOTICE, "NOTICE: Suboptimal snapshot"); + } + m_pdict = dictCreate(&dbDictType,this); - m_pdictTombstone = dictCreate(&dbDictTypeTombstone, this); + dictExpand(m_pdict, 1024); // minimize rehash overhead + m_pdictTombstone = dictCreate(&dbTombstoneDictType, this); serverAssert(spdb->m_pdict->iterators == 1);