必须用tc在主节点网卡出向对6379端口限速,因Redis无带宽控制参数;RDB传输与repl_backlog流直走TCP,绕过缓冲区限制;限速后须同步调大repl-timeout至≥120并启用repl-diskless-sync。

不能靠Redis配置限带宽,必须用tc在主节点网卡出向做端口级限速。 Redis本身不提供任何带宽控制参数,所有试图调小repl-backlog-size、增大repl-ping-slave-period或改client-output-buffer-limit slave的操作,都压不住RDB直传和repl_backlog TCP流的真实出口流量。
为什么Redis参数对带宽无效
真正吃带宽的是两个东西:全量同步时的RDB文件传输,以及增量同步时的repl_backlog数据流。这两者都绕过Redis缓冲区和心跳机制,直接走TCP socket发送——repl-backlog-size只影响内存缓冲区大小,client-output-buffer-limit slave只决定超限后是否断连,都不改变发包速率。你看到redis-cli --stat里out字节飙高,就是它们在“自由发挥”。
用tc对6379端口出向流量限速
这是唯一稳态可控的方法,关键不是“能不能限”,而是限得准不准、会不会导致从节点反复断连。操作前先确认主节点监听的网卡(如eth0)和端口(默认6379),然后执行:
tc qdisc add dev eth0 root handle 1: htb default 30 tc class add dev eth0 parent 1: classid 1:1 htb rate 50mbit ceil 50mbit tc filter add dev eth0 protocol ip parent 1:0 u32 match ip dport 6379 0xffff flowid 1:1
限速后务必验证:tc -s class show dev eth0看实时速率和丢包;若发现大量drop,说明rate设太低或repl-timeout没同步调大。
必须配套调整的Redis配置
单靠tc限速,不调Redis参数,大概率引发重试、CPU飙升或从库失联。三个动作要一起做:
- 开无盘复制:
CONFIG SET repl-diskless-sync yes,避免主节点先写RDB再读取的IO放大,让tc控的全是纯网络流 - 设延迟聚合:
CONFIG SET repl-diskless-sync-delay 5,防止多个从库同时重连触发多次bgsave - 调大超时:
CONFIG SET repl-timeout 120,否则限速后传输变慢,直接触发REPL_TIMEOUT重连
注意:repl-disable-tcp-nodelay设为yes能减少小包数量,但对RDB这种大块传输影响极小,别指望靠它降带宽。
最容易被忽略的一点:限速目标不是“越低越好”,而是让repl-timeout × 带宽 ≥ RDB大小 + backlog积压量。低于这个值,同步永远完不成。











