全量同步的流程与代价
全量同步是把主库的完整数据整体复制给从库的过程。主库先 fork 一个子进程生成 RDB 快照,同时把 fork 之后新到达的写命令暂存到复制缓冲区;快照传输到从库后,从库清空自身数据并加载,加载完成再接收缓冲区里累积的增量命令,此后转入正常的命令传播。整个过程对从库是「清空重来」,对主库则是一次额外的 fork、内存占用与网络带宽支出。
基本信息
| 触发时机 | 从库首次接入、复制 ID 不匹配、断连时间超过积压缓冲范围 |
|---|---|
| 步骤 | 主库 fork 生成快照、传输、从库清空并加载、补发增量命令 |
| 主库开销 | fork 停顿、COW 内存增量、出方向带宽 |
| 从库开销 | 清空数据、加载耗时、加载期间对外服务受限 |
| 观测字段 | INFO stats 的 sync_full 累计全量次数 |
典型使用场景
- 新从库接入:扩容或迁移时必然经历一次全量同步,应安排在低峰并预留带宽
- 故障恢复:从库数据被破坏或长时间离线后,需要重新全量同步才能恢复一致
- 容量评估:按数据集大小与带宽估算全量同步耗时,避免误以为「挂上就行」
- 排查反复全量:sync_full 持续增长说明链路或积压缓冲配置有问题,代价被反复付出
- 切换演练:主库替换后复制 ID 变化,从库可能被迫全量,需要提前评估新主库的承受能力
观测与判断
观测与判断
redis-cli INFO stats | grep -E 'sync_full|sync_partial_ok|sync_partial_err'
redis-cli -h 从库 INFO replication | grep -E 'master_sync_in_progress|slave_repl_offset'
redis-cli INFO replication | grep -E 'slave0|connected_slaves' # 主库侧看从库状态
redis-cli CONFIG GET repl-diskless-sync # 无盘复制可省去落盘步骤
redis-cli CONFIG GET repl-diskless-sync-delay # 等待多个从库一起传,提升带宽利用率
df -h /var/lib/redis # 落地方式下需预留快照空间各阶段的开销归属
| 阶段 | 主库开销 | 从库开销 |
|---|---|---|
| 生成快照 | fork 停顿与 COW 内存增量 | 无 |
| 传输快照 | 出方向带宽被占满 | 入方向带宽,磁盘写入(落盘方式) |
| 加载数据 | 无 | 清空并加载,期间对外服务受限 |
| 补发增量 | 发送缓冲区的命令 | 立即执行,转入正常复制 |
从库在全量同步期间可能拒绝对外服务:数据被清空后到加载完成之间存在窗口,默认 replica-serve-stale-data 为 yes 时会返回空数据或错误,具体行为与版本和配置有关。把从库用于读流量的架构应确认这个窗口的表现,必要时在切换前把流量摘掉。
全量同步不会自动限速:快照传输会占满主库出方向带宽,同一链路上其他从库的增量同步也会被拖慢,进而推高整体复制延迟。大实例扩容应逐个接入从库,避免多个全量同步同时进行。