dict是Redis的hash数据结构,用key值计算hashkey,元素插入到某个hash链上(拉链法解冲突)。hashtable(dictht)扩容是重要部分。
1)Redis“管家”函数serverCron依据算法(dict中used与size比值)判定是否扩容hashtable。2)dict中的ht[1]是扩容临时数据,3)扩容后,hashtable变长,hashtable的sizemask(哈希表大小掩码,计算索引值,总是等于size-1)与原来不同,计算出hashkey不同。4)对ht[0]中元素重新计算hashkey。
ps:在Rehash阶段,ht[0]元素rehash到ht[1]中,耗力重新计算hashkey。如果一次性完成一个dict的Rehash,将对其他任务造成延迟?
一、redis单线程渐进式rehash
只有一个线程在扩容(足够运行时间,不会饿死),扩容时其他线程可并发读写。过程:
1、ht[0],存数据table,非扩容容器。
ht[1],存数据table,扩容时才用,ht[0]的两倍。
2、扩容时(锁来保证同步性):单线程A从ht[0] copy到ht[1] 。其他线程:1)读/删:先去ht[0]找,找不到去ht[1]。 2)写:直接写在ht[1]中。
二、ConcurrentHashMap多线程协同式rehash
多个线程并发把数据从旧搬新,扩容过程:
A扩容从oldTable到newTable,其他线程
get:直接取,知道存放在oldTable或newTable中
写/删:如写的桶位,已到newTable。帮着扩容,扩容完成后才进行put操作。
https://blog.csdn.net/wangmaohong0717/article/details/84611426












网友评论