Skip to content

04.1 - 主从复制原理

定位: Redis 高可用的基石——通过数据副本提供冗余和读扩展 面试高频度: ⭐⭐⭐⭐⭐ 考查方式: 全量/增量复制流程、PSYNC2 优化、复制积压缓冲区、主从延迟


一、这是什么?为什么需要它?

是什么

主从复制(Master-Slave Replication)是 Redis 将主节点数据自动同步到一个或多个从节点的机制。

为什么需要主从复制?

单机 Redis 的问题:

  1. 单点故障——宕机了服务全停
  2. 读写都在一台——读多写少场景浪费 CPU
  3. 数据没有副本——持久化文件坏了就完了

主从复制的解决:

  1. 数据冗余:主挂→从顶(需配合 Sentinel)
  2. 读写分离:主写 / 从读
  3. 故障恢复:从节点有完整数据副本
  4. 服务隔离:慢查询/备份在从节点进行

二、原理拆解

2.1 复制拓扑

2.2 全量复制流程

全量复制的痛点:

  1. 主节点 fork + BGSAVE(CPU + 内存翻倍)
  2. 传输 RDB 文件(网络带宽)
  3. 从节点清空 + 加载 RDB(阻塞服务) → 数据量大时,全量复制很"重"

2.3 增量复制与 PSYNC2

PSYNC2 优化(Redis 4.0+):

  • 之前的问题: 主节点重启 → runid 变了 → 全量复制
  • PSYNC2 的改进:
    • 主节点重启后从 repl_id/repl_offset(持久化)
    • 从节点断线重连时可以直接增量复制
    • 从节点重启后也保留 repl_id 信息
  • 本质: runid + offset 持久化到 RDB/AOF

2.4 主从延迟与一致性问题

延迟来源:

  1. 网络延迟(主从跨机房等)
  2. 从节点执行慢(单线程排队)
  3. 大 key(慢命令阻塞从节点事件循环)

监控主从延迟:

bash
127.0.0.1:6379> INFO replication
# slave_repl_offset:1234567  # 从节点复制位置
# master_repl_offset:1234590 # 主节点复制位置
# → offset 差值 = 待同步的数据量

一致性说明: Redis 复制 = 最终一致性(非强一致),主节点写成功就返回客户端 → 从节点异步同步 主节点宕机 → 未同步到从节点的数据丢失


三、图解全景


四、实战验证

4.1 搭建主从复制

bash
# 主节点(默认 6379)
redis-server --port 6379

# 从节点(6380)
redis-server --port 6380 --slaveof 127.0.0.1 6379

# 或者连接后手动设置
redis-cli -p 6380 SLAVEOF 127.0.0.1 6379

# 查看复制状态
redis-cli -p 6379 INFO replication
# role:master
# connected_slaves:1
# slave0:ip=127.0.0.1,port=6380,state=online,offset=100

redis-cli -p 6380 INFO replication
# role:slave
# master_host:127.0.0.1
# master_port:6379
# master_link_status:up
# slave_repl_offset:100

4.2 验证主从数据

bash
# 主节点写入
redis-cli -p 6379 SET greeting "Hello from master!"

# 从节点读取
redis-cli -p 6380 GET greeting
# "Hello from master!"  ← 数据已同步

# 从节点是只读的
redis-cli -p 6380 SET test "should fail"
# (error) READONLY You can't write against a read only replica.

4.3 模拟断线重连

bash
# 1. 查看从节点复制偏移量
redis-cli -p 6380 INFO replication | grep slave_repl_offset

# 2. 停止从节点
redis-cli -p 6380 DEBUG SLEEP 30  # 模拟从节点卡死 30 秒

# 3. 这段时间主节点持续写入
for i in {1..1000}; do
  redis-cli -p 6379 SET "key:$i" "val:$i" > /dev/null
done

# 4. 从节点恢复后查看复制状态
redis-cli -p 6380 INFO replication | grep master_link_status
# master_link_status:up  # 自动恢复连接
# 且显示的是增量同步(非全量)

五、面试视角

追问答案要点
全量复制和增量复制的区别?全量:首次或断线太久,传输 RDB 文件(重);增量:断线重连后只传缺失命令(轻)
复制积压缓冲区的作用?环形缓冲区记录最近操作,让短时断线的从节点可以增量同步而不是全量
PSYNC2 解决了什么?主节点重启后 runid 不变,从节点不需要全量复制(Redis 4.0+)
主从复制是同步还是异步?异步。主节点写入内存立即返回客户端,从节点异步同步——所以不是强一致
主从延迟如何监控?INFO replication 查看 offset 差值和 master_last_io_seconds_ago
级联复制有什么好处?减轻主节点 RDB 传输的网络压力,A→B→C 的拓扑
主从复制跟持久化的关系?全量复制依赖 RDB;AOF 在从节点可做增量备份;两者结合是数据安全的基础

📚 相关链接

  • **哨兵 Sentinel** — 在主从基础上实现自动故障转移
  • **Redis Cluster** — 数据分片 + 高可用
  • **RDB** — 全量复制依赖 RDB
  • ← 返回 **高可用与集群索引**

Knowledge4J — Java 知识库