渐进式rehash


在了解redis的rehash之前,我们需要先了解下Redis的key和value的数据结构组织

Redis的key和value的数据结构组织

为了实现从键到值的快速访问,redis使用了一个全局哈希表来存所有的键值对。一个哈希表,其实就是一个数组,数组的每个元素称为一个哈希桶。所以通常会说,一个哈希表是由多个哈希桶组成的,每个哈希桶中保存了键值对数据。
在这里插入图片描述

哈希表的最大好处很明显,能用O(1)的复杂度查找键值对。
但是当往redis写入大量数据后,就可能发现操作有时候变慢了,这就可能是哈希冲突和rehash带来的阻塞操作。

redis存储结构

在这里插入图片描述

rehash

比如entry1和entry2在数组长度为6时,entry1的哈希值是3,entry2的哈希值是9,在数组中都在3号下面。此时数组扩容到12,那么entry2会移动到9下面。所以rehash会带来阻塞操作,不阻塞的话会有安全问题。
渐进式rehash指的是扩展或收缩哈希表时,需要将哈希表1里的所有键值对rehash到哈希表2中,这个rehash动作并不是一次性,集中式的完成的,而是分多次,渐进式的完成的。主要是因为:如果哈希表里保存的键值对的数量很大时,一次性的完成rehash的动作会导致服务器停止很长时间。

大致流程举例

在拷贝数据时,redis依然正常的处理请求。每处理一个请求时,从哈希表1中的第一个索引位置开始,将这个索引位置上的所有entry全部拷贝到哈希表2中;处理下一个请求时,再将下一个索引位置的所有entry拷贝到哈希表2中。

渐进式rehash操作时,除了根据键值对的操作进行数据迁移,redis本身还会有一个定时任务来执行rehash。没有键值对操作时,这个定时任务会周期性的(例如100ms一次)搬移一些数据到新的哈希表中,这样可以缩短整个rehash的过程。
#两种rehash的时机:
——每次处理客户端的请求时,一次只搬迁一个桶。
——redis定时任务,一次执行1ms,最少搬迁100个桶。

rehash的扩容时机

只有在添加添加元素的时候才会去判断是否需要扩容
只有当used是size的5的倍的时候才触发扩容(负载因子:dict_force_resize_ratio)

触发rehash操作的时机

缩容: Redis 定时任务 serverCron 会在每个周期内检查 bucket 的使用情况。当存放 key 的数量和总 bucket 数的比例小于 HASHTABLE_MIN_FILL(10%),触发缩容 Rehash 操作。
扩容:在每次调用 dictAddRaw 新增数据时,会检查 bucket 的使用比例。扩容的条件是以下之一:
dict_can_resize = 1 (该参数会在有 COW 操作的子进程运行时更新为 0,防止在子进程操作过程中触发 Rehash,导致内核进行大量的 Page 复制操作)
当前存放的 key 的数量与 bucket 数量的比例超过了 dict_force_resize_ratio(5)

Q:这种方式会不会造成空间开销过大?

数组的空间占用只有一小部分,占用空间比较大的是entry。
在这里插入图片描述

Q:一个桶本来已经rehash了,再有新增的entry怎么办?

在进行渐进式 rehash 的过程中, 字典会同时使用 ht[0] 和 ht[1] 两个哈希表, 所以在渐进式 rehash 进行期间, 字典的删除(delete)、查找(find)、更新(update)等操作会在两个哈希表上进行(但是,在非rehash期间,只使用一个哈希表)。 比如说, 要在字典里面查找一个键的话, 程序会先在 ht[0] 里面进行查找, 如果没找到的话, 就会继续到 ht[1] 里面进行查找, 诸如此类。 另外, 在渐进式 rehash 执行期间, 新添加到字典的键值对一律会被保存到 ht[1] 里面, 而 ht[0] 则不再进行任何添加操作: 这一措施保证了 ht[0] 包含的键值对数量会只减不增, 并随着 rehash 操作的执行而最终变成空表。

  • 26
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值