Java|阿里面试官:HashMap 熟悉吧?好的,那就来聊聊 Redis 字典吧!( 三 )

ht[0
哈希表上table数组第 rehashidx索引上所有节点都迁移到 ht[1
 中 。

当操作完成之后 , 再将 rehashidx 属性值加 1 。
最后当所有键值对都 rehash 到 ht[1
中时 , rehashidx将会被重新设置为 -1 。
虽然渐进式的 rehash 操作减少了工作量 , 但是却带来键值操作的复杂度 。
这是因为在渐进式 rehash 操作期间 , Redis 无法明确知道键到底在 ht[0
中 , 还是在 ht[1
 中所以这个时候 Redis 不得不查找两个哈希表 。
以查找为例 , Redis 首先查询 ht[0
  , 如果没找到将会继续查找 ht[1
除了查询以外 , 更新 , 删除也会执行如上的操作 。
添加操作其实就没这么麻烦 , 因为ht[0
不会在使用 , 那就统一都添加到 ht[1
 中就好了 。
最后我们再对比一下 Java HashMap 扩容操作 , 它是一个一次性操作 , 每次扩容需要将所有键值对都迁移到新的数组中 , 所以如果数据量很大 , 消耗时间就会久 。
总结Redis 字典使用哈希表作为底层实现 , 每个字典包含两个哈希表 , 一个平时使用 , 一个仅在 rehash 操作中使用 。
哈希表总的来说 , 跟 Java HashMap 真的很类似 , 底层实现也是一个数组加链表数据结构 。
最后 , 当对哈希表进行扩容操作时间 , 将会采用渐进性 rehash 操作 , 慢慢将所有键值对迁移到新哈希表中 。
其实了解 Redis 字典的其中的原理 , 再去比较 Java HashMap, 其实可以发现这两者有如此多的相似点 。
所以学习这类知识时 , 不要仅仅去背 , 我们要了解其底层原理 , 知其然知其所以然 。