面试题答案
一键面试Redis字典渐进式rehash过程
- 触发条件:当Redis字典的负载因子(load factor)过高(通常负载因子达到1,且字典中元素数量大于
dict_force_resize_ratio
设定的值,默认为512)或者负载因子过低(小于0.1)时,会触发字典的扩展或收缩操作,进而开始渐进式rehash。 - 初始化:Redis会分配一个新的哈希表(更大或更小,取决于扩展还是收缩),然后将字典中的
rehashidx
字段设置为0,表示rehash开始,并且指向旧哈希表的第一个索引位置。 - 渐进式迁移:在每次执行字典的插入、删除、查找或者更新操作时,除了执行原本的操作外,Redis会额外将旧哈希表中
rehashidx
指向的位置上的所有键值对迁移到新哈希表中,并将rehashidx
加1。这样每次操作都会迁移一小部分数据,而不是一次性迁移所有数据。 - 完成迁移:当旧哈希表中的所有键值对都被迁移到新哈希表中后,
rehashidx
的值会被设置为 -1,表示rehash过程结束,同时旧哈希表会被释放,新哈希表开始正式使用。
对内存管理的具体影响
- 内存使用效率
- 优点:渐进式rehash避免了一次性rehash带来的大量数据迁移开销,不会在短时间内占用过多的额外内存进行数据迁移。每次操作只迁移少量数据,使得系统在rehash过程中仍然能够保持相对较好的性能,对内存使用效率影响较小。
- 缺点:在rehash过程中,新旧两个哈希表会同时存在,会占用额外的内存空间,直到rehash完成旧表被释放。这在一定程度上降低了内存的使用效率。
- 峰值内存
- 增加峰值内存:由于渐进式rehash过程中存在新旧两个哈希表同时占用内存的阶段,所以在这个阶段内存使用会达到峰值,峰值内存大小为新旧两个哈希表所占用内存之和。相比一次性rehash(只有在迁移瞬间存在峰值,迁移完成后立即释放旧表内存),渐进式rehash的峰值内存持续时间更长。但由于每次迁移数据量小,系统整体性能波动小,不会因一次性大量内存分配和数据迁移导致系统卡顿等问题。
- 内存规划:开发人员在进行系统内存规划时,需要考虑到渐进式rehash过程中峰值内存增加的情况,合理配置系统内存,避免因内存不足导致系统故障。