- 共享复制缓存区
- 老版本多从库时主库内存占用过多(每个从库都有一个从库复制缓冲区)
- Redis 为了提升多从库全量复制的效率和减少 fork 产生RDB 的次数,会尽可能的让多个从库共用一个 RDB
- 将 ReplicationBuffer 数据切割为多个 16KB 的数据块 (replBufBlock),然后使用链表来维护起来
- ReplicationBuffer 由多个 replBufBlock 组成链表,当复制积压区或从库对某个block 使用时,便对正在使用的 replBufBlock 增加引用计数
- 当从库使用完当前的 replBufBlock(已经将数据发送给从库)时,就会对其 refcount 减 1 而且移动到下一个 replBufBlock,并对其refcount 加1
- 老版本多从库时主库内存占用过多(每个从库都有一个从库复制缓冲区)
- ReplicationBuffer 的裁剪和释放
- ReplicationBuffer 不可能无限增长,Redis 有相应的逻辑对其进行裁剪,简单来说,Redis 会从头访问 replBufBlock 链表,如果发现 replBufBlock refcount为0,则会释放它,直到迭代到第一个 replBufBlock refcount 不为0 才停止
- 当从库使用完当前的 replBufBlock 会对其refcount 减1
- 当从库断开链接时会对正在引用的 replBufBlock refcount 减1,无论是因为超过client-output-buffer-limit 导致的断开还是网络原因导致的断开
- 当 ReplicationBacklog 引用的replBufBlock 数据量超过设置的该值大小时,会对正在引用的 replBufBlock refcount 减1,以尝试释放内存
- 当一个从库引用的 replBufBlock 过多,它断开时释放的 replBufBlock 可能很多,也可能造成堵塞问题,所以Redis7 里会限制一次释放的个数,未及时释放的内存在系统的定时任务中渐进式释放
- ReplicationBuffer 不可能无限增长,Redis 有相应的逻辑对其进行裁剪,简单来说,Redis 会从头访问 replBufBlock 链表,如果发现 replBufBlock refcount为0,则会释放它,直到迭代到第一个 replBufBlock refcount 不为0 才停止
- 使用 Rax 树实现对 replBufBlock 固定区间间隔的索引,每 64 个记录一个索引点
- Rax 索引占用的内存较少;查询效率也是非常高
- streams 里面的 consumer group (消费者组) 的名称还有和 Redis 集群名称的存储也是使用的 Rax 树
- Trie 字典树(前缀树)
- Rax 基数树(前缀压缩树):压缩后的 Trie 树
上一篇

2024-09-11
下一篇

2024-09-10