渐进式 rehash 是 Redis 用来优化数据结构性能的一种算法。渐进式 rehash 不是一种简单的 rehash 算法,它结合了数据结构、哈希表和数据持久化等技术,通过在数据结构中插入新键和删除旧键的方式,实现了对 Redis 数据结构的优化。 二、源码分析dictRehash函数 dictRehash函数的实现如下(dict.c): /* Performs N ste...
可以看到,如果已经正在rehash了,直接返回,不允许多次rehash。 先找到有存储数据的rehash index,得到一个指针数组;然后遍历这个链表,对遍历到的所有结点进行rehash,采用头插法的方式进行赋给ht[1];再将ht[0]的元素减一,ht[1]的元素加一。 链表遍历rehash完之后,将对应槽位置空,并进入下一个槽位进行rehash的过程。
_dictRehashStep: 在dict执行操作过程中会调用_dictRehashStep函数执行一轮 Rehash 操作。 dictAddRaw: 该函数在执行数据插入操作前,会调用_dictRehashStep执行一轮 Rehash 操作。 dictGenericDelete: 该函数在执行物理/逻辑删除数据前,会调用_dictRehashStep执行一轮 Rehash 操作。 dictFind: 该函数在执行查询数据操作...
*/ dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing) { long index; dictEntry *entry; dictht *ht; // 判断是否正在ReHash,如果需要则调用_dictRehashStep(后续ReHash中的步骤),每次ReHash一条数据,直到完成整个ReHash if (dictIsRehashing(d)) _dictRehashStep(d); /* 获取新元素的...
那要解决的问题,主要是尽量使hash 碰撞的概率减小,解决方案便是进行hash表的扩容。而上面提到的两个ht_table表就是为了在扩容或是缩容时使用的。来看下具体的源码 rehash 的过程是从ht_table[0]中,按索引的位置,将该bucket中的列表逐个迁移到ht_table[1]中,这也是为了防止在迁移过程中长时间的阻塞导致redis...
具体执行rehash的是dictRehash方法(代表rehash的一步,步长由参数n来控制)。这是个具有一定通用性的方法,整体逻辑就是用两个hashtable,“左手倒右手”地来优雅地实现rehash: intdictRehash(dict*d,intn){intempty_visits=n*10;/* Max number of empty buckets to visit. */if(!dictIsRehashing(d))return0;...
dict rehash缩小流程: 源码函数调用和解析: serverCron->tryResizeHashTables->dictResize->dictExpand serverCron函数是个心跳函数,调用tryResizeHashTables段为: int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { ... if...
今天群里有个小伙伴问rehash的事。翻看下源码,解密下rehash。 我们小了解下rehash是什么 rehash有两个目的: (扩容)扩容防止hash冲突后,形成链表带来的性能下降,时间复杂度提升(5倍容量后才扩容); (缩容)大量key被回收后,大量的空闲空间,通过rehash节省空间(1/10以下使用量才缩容); ...
1.在扩容层面上,常规情况下,Redis认为哈希表节点数量与哈希表节点桶的个数应该是1:1的关系,一旦0号哈希表used/size>1,则需要进行Rehash扩容;此外还有一种特殊情况,就是redis在fork出子进程执行持久化等操作时,Redis会提高哈希因子触发Rehash的门槛,即used/size>5的时候才会进行,这是因为现代操作系统对于fork系统调...