主从同步卡在rdb传输阶段主要因带宽低估、tcp缓冲区不足、repl-backlog-size过小、client-output-buffer-limit过严及thp开启导致fork延迟;需逐项排查网络重传、真实吞吐、内核参数、缓冲区配置与内存管理。

主从同步卡在RDB传输阶段?先看带宽是否被低估
Redis全量同步时,主节点生成bgsave后要把整个RDB文件发给从节点——这个过程不是“瞬间完成”的,而是实实在在的网络IO。很多团队误以为内网千兆带宽“肯定够”,结果发现RDB传输动辄几十秒,甚至超时断连。根本原因常是:**带宽预估没扣掉系统开销,也没考虑TCP缓冲区和突发流量挤压**。
- 用
redis-cli --stat或netstat -s | grep -i "retransmit"确认是否存在重传;重传率>0.1% 就说明网络链路或缓冲区已成瓶颈 - 实测RDB大小:
du -h dump.rdb(主节点上查),再除以实际传输耗时(INFO replication里看master_repl_offset增长斜率),反推真实吞吐。若远低于理论带宽(如百兆网只跑8MB/s),大概率是TCP窗口或网卡中断队列压不住 - 别只盯着“带宽”,检查
/proc/sys/net/ipv4/tcp_rmem和tcp_wmem:默认四K级缓冲在大文件传输下极易打满,建议调为4096 65536 4194304(min/default/max)
repl-backlog-size设小了,RDB传一半就退化成全量重传
很多人以为repl-backlog-size只是为“断线重连”服务的,其实它直接影响RDB传输的稳定性。当从节点接收RDB慢于主节点写入速度,主节点会把新命令往复制积压缓冲区里塞;一旦缓冲区溢出,从节点重连后无法做部分同步,只能再次触发全量——形成“传RDB→溢出→重传RDB”的死循环。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 按公式算底线值:
QPS × 平均命令字节数 × 最长容忍断连时间。例如写QPS=3000、平均命令200B、容忍断连90秒 → 至少需3000 × 200 × 90 = 54MB - 生产环境直接设
repl-backlog-size 1024mb更稳妥:它是环形缓冲,设大不占额外内存,只影响主节点内存中一段固定区域 - 注意:该参数必须在主节点配置,从节点设无效;且修改后需重启或
CONFIG REWRITE持久化,仅CONFIG SET在重启后丢失
client-output-buffer-limit slave限制太紧,RDB还没发完就被踢
主节点用client-output-buffer-limit slave控制每个从节点的输出缓冲上限。这个缓冲区不仅存增量命令,还承载着整个RDB文件的发送流。如果RDB有2GB,而限制只设了256MB,主节点会在发到256MB时强制断开连接——从节点日志报Connection with master lost,但你根本看不到RDB传输失败的明确提示。
- 检查当前值:
CONFIG GET client-output-buffer-limit,典型返回类似"slave 268435456 67108864 60"(硬限256MB,软限64MB,超软限60秒触发断连) - 安全做法:硬限至少设为预期最大RDB体积的1.5倍。例如RDB通常1.2GB → 设
slave 1800000000 0 0(即1.8GB,软限关掉) - 风险提示:该值调太大不会导致OOM,但若从节点长期假死,主节点会持续堆积数据直到OOM;所以得配合监控
slave0:output_buffer指标做告警
THP开启+大RDB=fork延迟翻倍,bgsave拖垮同步节奏
当主节点执行bgsave生成RDB时,Redis靠fork()创建子进程。若系统启用了透明大页(THP),fork的写时复制(COW)单位从4KB变成2MB——意味着哪怕只改一个字节,也要拷贝2MB内存页。RDB越大,fork越慢,主线程卡顿越久,从节点等不到数据,延迟自然飙升。
- 查THP状态:
cat /sys/kernel/mm/transparent_hugepage/enabled,若显示[always]或[madvise],必须关 - 临时关闭:
echo never > /sys/kernel/mm/transparent_hugepage/enabled - 永久关闭:在
/etc/default/grub的GRUB_CMDLINE_LINUX加transparent_hugepage=never,再update-grub && reboot - 顺手检查
INFO memory里的mem_allocator,避免用jemalloc旧版本(<5.2.1)在THP关闭后仍残留页对齐问题










