why技术

渐进式。。。

你好呀,我是歪歪。

我知道你看到渐进式这个标题的时候想到的那个渐进式。

但是其实我说的这个渐进式不是你想到的那个渐进式。

Image

我说的这个渐进式是在 Redis 里面,针对 rehash 的过程,有个叫做渐进式哈希的机制。

假如 Redis 中有大量的 key, 如果一次性对全部的数据进行 Rehash,在加上“Redis 是单线程”的这个设定,那么可能会导致 Redis 在 Rehash 的过程中对外表现出性能拉胯的情况。

所以渐进式 rehash 技术允许 Redis 在不影响整体服务的情况下,逐步地将数据从旧的哈希表迁移到新的哈希表中。

渐进式 rehash,听起来很高大上,但是这个过程,梳理起来也还是比较简单的。

也是经常出现在面试环节中,所以歪师傅带你简单的盘一下。

首先渐进式 rehash 在开始时,Redis 会在内存中创建一个新的空哈希表,并且保留原有的哈希表。这意味着 Redis 在 rehash 过程中会同时持有两个哈希表,假设我们叫做 why[] 和 max[]。

那么既然是渐进式的,进度肯定是缓慢的,那么怎么才能知道当前的“渐进”的进度是多少了呢?

在这个过程中,会维护一个叫做 rehashidx 计数器,将它的值初始化为 0,这标志着 rehash 工作的开始。

此变量用于追踪当前 rehash 的进度,每完成一部分迁移,rehashidx 的值就会递增。最终在某个时间点上,哈希表 why[] 的所有键值对都会被 rehash 至哈希表 max[]。

这时 Redis 会将 rehashidx 属性的值设为 -1 , 表示 rehash 操作已完成。

同时,在 rehash 进行的期间,每当有添加、删除、查找或更新操作发生时,Redis 就会将 rehashidx 索引位置的旧哈希表中的键值对重新计算哈希值并迁移到新哈希表中。

这样就将 rehash 的工作分散到了多次的 crud 操作中,由一次性集中搞,一刀切,改成了小步调整,逐步到位,避免了 Redis 阻塞。

u1s1,虽然渐进式 rehash 可以避免 Redis 阻塞,但它同时也意味着在 rehash 过程中,Redis 需要同时维护两份哈希表,这可能导致内存使用量暂时性地增加。

但是,注意我要说但是了啊。

但是和性能以及稳定性比起来,内存,廉价到不值一提。

那么就有小伙伴要问了:Redis 啥时候会触发渐进式 rehash 呢?

主要用于 Redis 需要动态调整哈希表大小的情况,一种情况是数据减少使得当前哈希表过大导致资源浪费时,一般来说这种情况比较少见。

多见的一种情况是这样的,甚至我们可以用一个公式来套一下:

xx 增长导致现有 xx 不足以满足 xx 需求时。

在 Redis 中,当数据增长导致现有哈希表不足以满足性能需求时,就会触发渐进式 rehash。

渐进式 rehash,说穿了,也就这么一点事儿。

我知道你看到渐进式这个标题的时候想到的那个渐进式。

结果点进来之后发现我说的渐进式不是你以为的那个渐进式。

但是我说的这个渐进式还是很简单的,不管是背景还是实现方式。

不像是你以为的那个渐进式,不管是背景还是实现方式都有点复杂。

只能说我们要在渐进的年龄中,从各个角度渐渐的理解你以为的那个渐进式。

问题的关键就是要抓住关键的问题。

渐渐的渐进式就是要在渐进式中渐渐。

··············  END  ··············

Image

你好呀,我是歪歪。我没进过一线大厂,没创过业,也没写过书,更不是技术专家,所以也没有什么亮眼的title。

当年高考,随缘调剂到了某二本院校计算机专业。纯属误打误撞,进入程序员的行列,之后开始了运气爆棚的程序员之路。

说起程序员之路还是有点意思,可以点击蓝字,查看我的程序员之路。