Redis 主从复制

主从复制(Replication)让一台主库把数据同步到若干从库:主库负责写,从库分担读,并作为故障切换的备用节点。它是哨兵高可用与集群方案的基石。

配置一个从库

从库只需知道“主库是谁”。在从库配置文件中写 replicaof(新写法,替代旧的 slaveof):

replicaof 192.168.1.10 6379   # 从库启动后自动跟随该主库
replica-read-only yes         # 从库默认只读,防误写造成分叉

也可以运行时动态指定,立即生效:

127.0.0.1:6379> REPLICAOF 192.168.1.10 6379
# 输出:OK
127.0.0.1:6379> INFO replication
# 输出:# Replication
#       role:slave
#       master_host:192.168.1.10
#       master_port:6379
#       master_link_status:up

全量同步与增量同步

  • 首次复制或断线太久:全量同步。从库发 PSYNC 携带自己的 replid 与偏移量,主库发现无法续传便 BGSAVE 生成 RDB 快照传给从库,从库清空本地后加载,再追赶积压的命令。
  • 正常运行:增量同步。主库每执行一条写命令就实时转发给从库,同时写入复制积压缓冲区 repl backlog。
  • 用 master_replid 标识数据流、master_repl_offset 标识复制进度,二者都在 INFO replication 中可查。

主库一侧可看到从库状态与复制偏移:

127.0.0.1:6379> INFO replication
# 输出:# Replication
#       role:master
#       connected_slaves:1
#       slave0:ip=192.168.1.11,port=6379,state=online,offset=3521,lag=0
#       master_repl_offset:3521

拓扑与读写分离

主从复制拓扑与同步

  • 一主多从:一个主库挂多个从库,最常见的读扩展形态。
  • 链式复制:从库 A 再挂从库 B(A→B),减轻主库分发连接的负担。
  • 应用把读请求打到从库、写请求打到主库,就实现了读写分离。

从库默认只读,对从库执行写命令会报错:

127.0.0.1:6379> SET k 1
# 输出:(error) READONLY You can't write against a read only replica.

从库晋升为主

演练或主库故障时,让某从库脱离关系独立成主:

127.0.0.1:6379> REPLICAOF NO ONE
# 输出:OK

此后其他从库再 REPLICAOF 指向它即可。手工晋升是理解哨兵自动故障转移的基础。

延迟与常见坑

  • 复制是异步的:主库写完即返回,从库可能有短暂滞后,强一致读不能依赖从库。
  • 断线过久或 backlog 太小会退化成全量同步,瞬间压力大;可调大积压缓冲区扩大增量续传窗口:
repl-backlog-size 64mb        # 默认 1mb,写频繁的实例建议调大
  • 全量同步瞬间主库要 fork 子进程做 BGSAVE 并传输 RDB,注意内存与带宽余量。
  • 复制≠持久化:主库若关闭持久化,从库可能被“空主库”全量同步清空,见持久化一章。

小结:主从复制提供“单写多读 + 数据冗余”,配置只需 replicaof 一行;写走主、读走从,并用 repl backlog 缓解断线重连。要自动切换主从,则交给下一章的哨兵。

笔记加载中…