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 最长可以离线多久而仍能进行增量同步。

相关推荐
唐青枫3 小时前
Java ReentrantLock 实战详解:比 synchronized 更灵活的可重入锁
java
练习时长一年3 小时前
@SneakyThrows注解
开发语言
我的xiaodoujiao3 小时前
快速学习Python基础知识详细图文教程14--模块
开发语言·python·学习·测试工具
wdfk_prog3 小时前
嵌入式面试真题学习笔记系列
笔记·学习·面试
懿路向前3 小时前
【HarmonyOS学习笔记】2026-07-30 | 小艺开放平台智能体接入实战
笔记·学习·harmonyos
NoteStream3 小时前
【c语言基础】C语言常见概念
c语言·开发语言·编辑器
吃好睡好便好4 小时前
MATLAB中图像的线性变换
开发语言·图像处理·学习·计算机视觉·matlab
charlie1145141914 小时前
Cinux —— 给物理内存建账本:bitmap 物理内存管理器
开发语言·c++·操作系统·开源项目
YUS云生4 小时前
大模型学习·第41天:LangChain进阶——提示词模板与Chain链式调用
学习·langchain·c#
ShiXZ2134 小时前
Java 8 Stream API 实用技巧详解:从入门到精通
java·开发语言