redis里的key是保存在一个类似hashmap的结构里,扩容的时候取模是这样的,比如值=3,结构大小=8.那么这个3的位置:
3 mod 8 = 3 &(8-1) = 3&7 =3; 3 = 011
扩容成16后:
3 mod 16 = 3 & 15 = 11; 11 = 1011
& 等于是一个位与操作。
比作hashMap的话,就是3这个entry上挂着的那个链表,会被hash到新链表的3和11两个entry上。
这个的话,可以提一下concurrentHashMap扩容的时候,过程大概这样:先更具entry数组的大小来分配线程数量,每个线程管理16个。然后在扩容是,加上锁。对entry下面的链表,根据节点元素的hash值对新链表长度取模分为两块:
取模=0的放在原来的低位,比如3
取模=1的放在高位,比如11.
原因:参考:https://www.jianshu.com/p/dc69edc17b32 hashmap博大精深。。。。
扯远了。。。
redis的话用的是高位进位的加法,当rehash后,两个新的entry位置是相邻的,这时候遍历起来就只要往后遍历就行了,具体参考:《REDIS深度历险》 p84. 极大的暴露了我进制运算差的本质。。。。。
渐进式reHash的话,就是会生成一个新的数组,但如果旧数组数量很大但话就会造成卡顿。所以会同时保留两个数组,scan遍历的时候会扫描两个,旧的没有就去扫描新的。后台的任务会逐步把数据更新到新数组。
redis字典结构和渐进扩容
最新推荐文章于 2024-01-08 21:56:19 发布