关于redis:redis渐进式rehash

60次阅读

共计 1118 个字符,预计需要花费 3 分钟才能阅读完成。

引言

简略温习一下,redis 有哪些数据结构和对象。

数据结构

  1. 间断内存类

    1. SDS 简略动静字符串
    2. 整数汇合 intset
    3. 压缩链表 ziplist
  2. 随机内存类

    1. list 和 listnode
    2. zskiplist 和 zskiplistnode
  3. 间断 + 随机:dict、dictht 和 dictEntry

对象

总共有 5 种:

  1. string
  2. list
  3. hash
  4. set
  5. zset

其中,hash 对象的外部实现是 redis 的字典,也就是 dict 构造,dict 构造有两个字段和 rehash 无关:

  1. 两个 hash 表(hash 表是 dictht 构造)
  2. rehashidx,记录 rehash 的进度

渐进式 rehash

须要渐进式 rehash 的起因:

  1. 随着 client 对 hash 对象的增删数据操作,hash 对象里的元素会相应的减少或缩小,导致内存利用率变低或减少 hash 碰撞几率,因而须要对其底层的哈希表进行扩缩容。扩缩容的规范是底层哈希表的负载因子;
  2. 扩缩容,须要相应地从新计算 key 在新的哈希表中的地位,这是一个耗费 cpu 算力的操作;

这就是渐进式 rehash 呈现的起因,rehash 的需要加上一次性 rehash 的性能问题。

渐进式 rehash 触发的条件

分为扩容和缩容:

  1. 扩容,分为有没有正在执行 bgsave(生成 RDB 文件)或 bgrewriteaof 命令(重写 AOF)

    1. 正在执行,判断负载因子 >=5
    2. 没有在执行,判断负载因子 >=1

    已知生成 RDB 文件或重写 AOF 也是比拟耗费 cpu 算力的操作,因而对这两个数值的不同,就能够了解了。

  2. 缩容:简略粗犷,负载因子 <=0.1

附上负载因子计算公式:used / size(哈希表已应用的键数量 / 容量)

渐进式 rehash 的过程

参考:https://tech.meituan.com/2018…

在没有 rehash 时,dict 构造外面的两个 dichht 构造,有一个的 table 指向的是空指针,即,这个样纸:

基于此状态形容渐进式 rehash(扩容状况下)的过程:

  1. 为 ht[1] 调配一块新的内存,内存空间大小依照 DICT_HT_INITIAL_SIZE * 2 的 n 次方 >= h[0].used,这里 >= 的意思是第一个大于 h[0].used 的值;(在 rehash 过程中会始终维持这个内存耗费);
  2. 在 rehash 过程中,所有对 h[0] 的删改查操作,都会触发 h[1] 同样的操作,同时进行一次 rehash,把 h[0] 的中 h[0].table[rehashidx] 地位的数据挪到 h[1],而后给 rehashidx+1;新增操作则会间接放到 h[1] 中;
  3. 每次 rehash 函数最初会判断 h[0].used==0,if true,完结渐进式 rehash 过程。

参考:https://blog.csdn.net/weixin_…

正文完
 0