bgsave的fork会卡主节点,因其需同步复制页表项,内存越大、碎片越多、THP开启或vm.overcommit_memory=0时,耗时可达数百毫秒至秒级,期间主线程假死。

全量复制本身不会阻塞主节点,但 bgsave 过程中 fork 子进程可能引发秒级卡顿,尤其在大内存、高负载场景下。
为什么 fork 会卡主节点?
主节点执行全量同步前必须生成 RDB 快照,这依赖 bgsave。而 bgsave 的实现是 fork 一个子进程——fork 不复制物理内存,但要拷贝页表项。当主节点内存达几十 GB 且内存页碎片多时,fork 耗时可能达数百毫秒甚至秒级。这段时间主线程无法处理新请求,表现为“假死”或响应延迟飙升。
- Linux 内核需为子进程逐页复制父进程的虚拟内存映射(vma),页数越多越慢
- 开启透明大页(THP)会显著恶化 fork 耗时,应禁用:
/sys/kernel/mm/transparent_hugepage/enabled设为never - 内存使用率 >80% 时,fork 更容易触发内存分配等待,加剧延迟
哪些配置或行为会让问题更严重?
不是所有全量复制都一样卡,关键看主节点当前状态和配置:
-
vm.overcommit_memory = 0(默认):fork 前检查是否有足够内存分配给子进程,若实际可用内存不足(比如被缓存占满),fork 会阻塞等待,直到释放出足够页框 - 主节点正执行
KEYS、SCAN、SUNION等 O(N) 命令:CPU 和内存带宽被抢占,fork 更慢 - 启用了 AOF 且
aof-rewrite-incremental-fsync关闭:AOF 重写与bgsave可能竞争 I/O,间接拖慢 fork 后的子进程写盘
怎么确认是不是 fork 卡住的?
别只盯着 INFO replication 里的 master_repl_offset 是否增长,要看主线程是否真卡了:
- 用
redis-cli --latency测延迟突增(>100ms)的时间点,是否与全量同步开始时间吻合 - 查系统日志:
dmesg -T | grep -i "out of memory\|fork",看是否有 fork 失败或 OOM killer 记录 - 监控
INFO stats中的latest_fork_usec:该值超过 500000(500ms)就属于高风险,需优化
真正危险的不是“全量复制”这个动作,而是主节点在高内存压力、低内核调优、无监控覆盖的状态下盲目触发 fork。很多线上事故里,运维看到 psync fullresync 就以为是网络或从库问题,却没意识到主节点的 fork 已经把整个服务拖进泥潭。


















