Redis的渐进式Hash

614 阅读2分钟

redis的底层存储​

redis把所有的key都存储在一个大字典中,学过python的小伙伴应该就会知道字典这个数据结构,但是这个数据结构跟python的数据结构不一样,这个字典跟java里面的HashMap像似,

如图所示:

我们可以看到是数组+链表的结构,我们知道的Java中的HashMap每次扩容方式是当大于LoadFactor阈值时,就需要重新分配一个2倍的数组,就需要把所有元素都重新计算hash值操作(rehash)挂载到新的数组中, 数组的大小是2n,空间大小加倍 就变成了2​n+1

渐进式hash是什么呢?

我们知道的java的HashMap是一次性把所有的元素都重新rehash操作然后添加到新数组中,当HashMap元素多的时候,就会有线程卡顿的现象,到这里就该引出今天的主角 渐进式Hash​

渐进式Hash他在扩容的时候也会创建一个新数组,但是他会同时保留旧数组和新数组,然后在定时任务中以及对hash的指令操作中渐渐将旧数组中挂载的元素迁移到新数组中,Redis中在扩容的时候会存在俩个底层数组,所以当访问的时候需要同时访问新数组跟旧数组,当在旧数组找不到元素他旧会去新数组中找元素,那么当在旧数组找到元素后会干什么呢?Redis会把旧数组的元素通过在新数组hash操作计算添加到那个位置上面,就这样慢慢的把旧数组中的元素添加到新数组里面来,这就是渐进式Hash,在go语言的map的底层实现也是渐进式Hash,所以Reids的扩容大小跟HashMap扩容都是2倍的扩容