redis采用渐进式滚动的方式进行扩缩容rehash。
扩容过程:
1、当新加入数据调用dictAddRaw进行dict的添加时,redis进行判断是否进行扩容操作;
2、redis负载因子>=1则进行扩容操作,但当Redis 正在做 bgsave或者rewrite等操作时暂时不扩容,除非负载因子大于5才进行强制扩容。
3、redis使用_dictExpandIfNeeded函数进行扩容操作,扩容完成后则进行rehash操作(databaseCron或者redis的操作命令均能触发)。
缩容:
1、当databaseCron定时执行时检测到元素个数低于哈希桶分配的个数的 10%时,进行缩容。
2、当Redis 正在做 bgsave或者rewrite等操作不可缩容。
3、redis使用htNeedsResize进行判断是否缩容,dictResize进行缩容,缩容完进行rehah操作。
渐进式rehash:
1、dict的rehashidx作为是否rehah的条件,当为-1时不进行rehash,当为0时开始进行rehash。
2、每次对字典的增删查改操作时,都会判断是否正在进行rehash操作,是则需进行_dictRehashStep,每次跳过100个空桶然后将dt[0]的一个桶移入dt[1]中,并将rehashidx+1。
3、databaseCron定时检测是否进行rehash,是则执行dictRehashMilliseconds执行1ms,每次执行100个桶,超过1ms则退出本次rehash操作。
4、rehash完成时rehashidx置为-1,将dt[0]hash表释放,dt[0]指向dt[1],dt[1]重置,至此完成了rehash操作。