Redis repl_backlog 学习笔记

1. repl_backlog 是什么?

repl_backlog(复制积压缓冲区)是 Redis Master 维护的一块固定大小的内存,用于保存最近发送给 Slave 的复制流(Replication Stream)

它的主要作用:

  • 支持主从断线后的增量同步(PSYNC)

  • 避免每次断线都重新进行全量同步(RDB)

注意:保存的是复制流,通常表现为写命令,但本质上是 Master 发给 Slave 的同步数据,而不是简单的客户端历史命令。


2. repl_backlog 的数据结构

底层采用:

固定大小的环形缓冲区(Circular Buffer)

例如:

复制代码
+------------------------------+
|                              |
|        repl_backlog          |
|                              |
+------------------------------+

特点:

  • 大小固定

  • 写满后不会扩容

  • 从头开始覆盖最旧的数据

例如:

复制代码
第一次:

cmd1
cmd2
cmd3
cmd4

继续写:

cmd5
↓

覆盖 cmd1

因此:

数组内容会循环覆盖。


3. 什么是 offset?

除了 backlog,还有一个非常重要的概念:

复制偏移量(Replication Offset)

它表示:

复制流中的第几个字节。

Master 维护:

复制代码
master_repl_offset

Slave 也维护:

复制代码
slave_repl_offset

它们记录当前已经同步到了哪里。


4. offset 与环形数组的关系

这是最容易混淆的地方。

backlog

是一个固定大小的数组。

例如:

复制代码
100 字节

数组下标:

复制代码
0
1
2
...
99

写满以后:

复制代码
99
↓

0

重新开始

因此:

数组下标会循环。


offset

offset 不属于数组。

它代表整个复制流的位置。

例如:

复制代码
offset

1
2
3
...
100
101
102
...
100000
...

特点:

  • 一直递增

  • 不会因为数组覆盖而重新计数

  • 理论上会持续增长(Redis 使用 64 位整数,正常情况下几乎不用担心溢出)

因此:

数组内容是环状的,会发生覆盖;offset 会一直累加,不会回绕。


5. Master 如何判断是否可以增量同步?

假设:

当前 backlog 保存:

复制代码
offset

901 ~ 1000

Slave 汇报:

复制代码
我同步到了950

Master 发现:

复制代码
951~1000

还在 backlog 中。

于是:

复制代码
PSYNC
↓

发送951~1000

完成:

增量同步。


如果 Slave 汇报:

复制代码
800

Master 查看:

复制代码
801~900

已经被覆盖。

于是:

复制代码
FULLRESYNC

重新:

  • 生成 RDB

  • 全量同步

  • 再同步 RDB 生成期间的新命令


6. 为什么 backlog 要设计成环形?

如果一直保存所有复制数据:

复制代码
历史命令越来越多
↓

内存无限增长
↓

Redis 内存耗尽

因此 Redis 采用:

固定容量 + 覆盖旧数据

优点:

  • 内存固定

  • 写入效率高(O(1))

  • 非常适合缓存最近的数据


7. 如果 Master 一直工作,Slave 长时间宕机怎么办?

假设:

复制代码
Master
↓

持续写入

↓

backlog 不断覆盖旧数据

Slave 长时间离线后恢复:

如果缺失的数据:

  • 还在 backlog 中 → 增量同步(PSYNC)

  • 已经被覆盖 → 全量同步(FULLRESYNC)

因此:

Redis 只能保证一定时间内的增量同步,无法永久保存复制历史。


8. 生产环境如何减少全量同步?

主要方法:

(1)增大 backlog

例如:

复制代码
repl-backlog-size 256mb

或:

复制代码
repl-backlog-size 1gb

保存更多复制数据。


(2)保证 Slave 尽快恢复

减少长时间离线。


(3)接受全量同步

如果 Slave 离线太久,这是 Redis 的正常机制。


9. 核心总结(★★★★★)

  • repl_backlog 是 Master 保存最近复制流的固定大小环形缓冲区。

  • backlog 中的数据会不断覆盖最旧的数据。

  • Master 和 Slave 都维护自己的复制 offset。

  • 数组内容会循环覆盖,但 offset 会一直递增。

  • Slave 重连时,会上报自己的 offset。

  • 如果缺失的数据仍在 backlog 中,则执行 PSYNC(增量同步)

  • 如果缺失的数据已被覆盖,则执行 FULLRESYNC(全量同步)

  • backlog 的大小决定了 Slave 最长可以离线多久而仍能进行增量同步。

相关推荐
urkay-1 小时前
Kotlin Flow分类
android·开发语言·kotlin
并不喜欢吃鱼1 小时前
从零开始 C++----- 十五.一文吃透 C++ 异常:try-catch、栈展开、自定义异常、异常安全 noexcept 底层全剖析
java·开发语言·jvm
gr95ZS6E62 小时前
基础入门java安全(一)--CC1基础分析
开发语言·python
吴声子夜歌2 小时前
Redis 5.x——分布式锁
redis·分布式
智码看视界2 小时前
Day19 Spring Boot启动优化:启动时间从8秒降到2秒
java·spring boot·后端·启动优化
心中有国也有家2 小时前
AtomGit Flutter 鸿蒙客户端:初始化流水线
学习·flutter·华为·harmonyos
北京阿法龙科技有限公司2 小时前
AR智能眼镜安防应用核心指标:识别距离筑牢防线
java·开发语言·ar
杜子不疼.2 小时前
【C++】继承—C++的秘密武器,get父类的智慧
开发语言·c++
a1117762 小时前
SLAM 学习笔记(三)视觉里程计2(VO) 特征点法
人工智能·笔记·学习