7.1 主从复制:增量命令流 本节摘要:主从复制的本质是"从库重放主库的写命令流"。首次连接走全量同步(传 RDB 快照),断线重连时若偏移仍在复制积压缓冲内则走部分重同步(只补差量)。复制是异步的,这决定了它的性能上限与丢失窗口。 从一条 REPLICAOF 开始 连接建立后,从库的身份变成"只读副本",所有写命令被拒绝(可配置 replica-read-only,默认开)。读流量分散到从库,写集中在主库——读写分离的物理基础就这么简单。 复制健康度两侧对读,是本节最该练熟的一个动作。主库侧关注推送与积压: 从库侧关注链路与自身水位: 解读这两份报告的方法:主从水位相减就是复制延迟的字节数,配合业务写入速率可换算成秒级的陈旧窗口;lag 字段是从库视角的延迟秒数,持续大于一就该查网络;
本节摘要:主从复制的本质是"从库重放主库的写命令流"。首次连接走全量同步(传 RDB 快照),断线重连时若偏移仍在复制积压缓冲内则走部分重同步(只补差量)。复制是异步的,这决定了它的性能上限与丢失窗口。
# 从库上执行,指向主库 > REPLICAOF 10.0.0.11 6390 > INFO replication role:slave master_link_status:up slave_repl_offset:10538211
连接建立后,从库的身份变成"只读副本",所有写命令被拒绝(可配置 replica-read-only,默认开)。读流量分散到从库,写集中在主库——读写分离的物理基础就这么简单。
复制健康度两侧对读,是本节最该练熟的一个动作。主库侧关注推送与积压:
# 主库上执行 > INFO replication role:master connected_slaves:2 slave0:ip=10.0.0.12,port=6390,state=online,offset=10538211,lag=0 slave_repl_offset:10538211 # 主库当前水位 repl_backlog_size:1048576 # 积压缓冲容量,默认1MB repl_backlog_first_byte_offset:9529664
从库侧关注链路与自身水位:
# 从库上执行 > INFO replication role:slave master_host:10.0.0.11 master_link_status:up # down则链路断,读到的都是旧数据 master_last_io_seconds_ago:0 # 距主库最近通信的秒数 slave_repl_offset:10538010 # 自身水位
解读这两份报告的方法:主从水位相减就是复制延迟的字节数,配合业务写入速率可换算成秒级的陈旧窗口;lag 字段是从库视角的延迟秒数,持续大于一就该查网络;repl_backlog 两行相减是缓冲里现存的历史长度——它决定断线重连能不能走部分重同步,写流量大的实例这个缓冲要按"峰值写入速率乘预期断线时长"去配,默认 1MB 只够演示环境。
断线重连时的关键判断在主库侧:从库上报"我的复制ID加偏移量",若这个偏移还落在主库的复制积压缓冲(一个环形缓冲,默认 1MB)范围内,只补发差量命令;若偏移已被环形覆盖(断太久),退回全量同步。生产上大流量实例通常把这个缓冲调到 64MB 以上,就是为了少做昂贵的全量。
部分重同步为什么既要"复制 ID 相同"又要"偏移在窗口内",拆开看就懂:复制 ID 是主库数据版本的姓氏——主库重启或触发故障转移后,数据历史翻篇,旧 ID 下的偏移彻底作废,哪怕数字落在窗口内也无从补起;偏移在窗口内则保证"从库缺的那段命令还在环形缓冲里没被覆盖"。两个条件缺一,都只能走全量。运维推论也随之清晰:主库无谓的重启就是在制造全量同步,滚动发布时先升从库再升主库的顺序,省的就是这笔账。

主库执行完写命令立刻回复客户端,"转发给从库"是异步另发。网络抖动或从库慢时,主从之间存在秒级延迟——INFO replication 的 master_repl_offset 减 slave_repl_offset 就是积压字节数,这是监控主从健康最直接的数字。
延迟带来的两个工程事实。读到旧数据:写主读从时,刚写入的数据从库可能还没有。对策要分级——下单后的订单详情页这类"写后立刻读"走主库或做会话粘性,榜单、商品列表这类可容忍秒级陈旧的读放从库;不分场景全读主库,读写分离就白搭了。切换丢数据:主库崩溃瞬间未同步的命令永久丢失,这是第 6 章那句"Redis 到不了零丢失"的另一半。
⚠️ 常见坑:级联复制(从库再挂从库)能分摊主库推送压力,但拉长了同步链路,顶层故障时整链重新同步;复制风暴的预防靠"一主多从层级化加足够大的积压缓冲",而不是无脑平铺从库。
全量同步默认让主库先落一个 RDB 文件再传输;磁盘慢的宿主机上可用 repl-diskless-sync yes 改为边生成边通过网络发送,跳过磁盘这一跳。另外主库记得配 requirepass 加 masterauth:从库连主库也要密码,公网上裸奔的主从端口是真实发生过的事故来源。
排错速查,主从链路上的高频报错与第一动作:
| 报错或现象 | 病因 | 第一动作 |
|---|---|---|
| 从库 master_link_status:down | 网络不通或密码不匹配 | 核对 masterauth 与防火墙 |
| MASTERDOWN Link with MASTER is down | 从库被要求服务但链路断 | 先修链路,读请求临时回主 |
| 全量同步反复触发 | 积压缓冲太小、断线超出窗口 | 调大积压缓冲,查网络抖动 |
| 主库输出缓冲暴涨 | 从库消费慢,积压在主库内存 | 看 client-output-buffer-limit replica 限额与断连记录 |
反复全量同步是其中最伤的一种:每次全量都让主库 fork 一次、从库清库重灌,期间从库不可读,主库还要为它缓存增量。根因十有八九是"断线时长超过了积压缓冲能记住的范围",处方就是按峰值写入速率扩缓冲,并把网络抖动的根因(跨机房、虚拟机迁移)一并处理。