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

相关推荐
zhanghaha131418 分钟前
HTML系列教程:14_HTML 表单与输入框 <form>、<input> 零基础详解
java·前端·javascript
傻啦嘿哟5 小时前
某招聘平台爬虫:爬取招聘岗位数据,分析各城市薪资水平
开发语言·爬虫·python
2501_933670795 小时前
2026秋招量化分析岗技能栈:Python、SQL、统计建模、回测项目怎么准备
开发语言·python·sql
yxlalm6 小时前
Spring AI+RAG 01-项目背景与技术选型
java·人工智能·spring
传奇开心果编程6 小时前
【xilem0.4基础语法学与练】第13课:Xilem 0.4 最简短代码体现“一切皆设计图“
学习·rust·前端框架
小雪崩6 小时前
嵌入式学习 day45:51单片机基础
学习·51单片机
程序员清风6 小时前
Java 后端高并发设计:线程池、限流、熔断与降级
java·数据库·oracle
李少兄6 小时前
JavaScript 数据类型完全指南
开发语言·javascript·ecmascript
Seoyoneh7 小时前
Agentic Workflow编排架构:云客服从“被动响应”迈向“主动执行”的技术实现
java·开发语言·架构
海南java第二人7 小时前
对外 API 如何保证幂等性?插入数据 / 上传表格场景全方案汇总
java·幂等性