Redis主从复制中slave_repl_offset长时间不动,说明TCP连接正常但数据未同步,核心原因是集群总线端口16379被防火墙/NAT/安全组/Docker映射或bind配置拦截,导致主从间增量命令无法传输。

从节点显示 connected 但 slave_repl_offset 长时间不动,说明 TCP 连接建成了,数据却没流过去——这几乎一定是网络层“通而不传”,核心要查集群总线端口是否被拦、主从通信路径是否被转发规则破坏。
确认从节点是否真在收增量命令
别只看 cluster nodes 或 INFO replication 里状态是 online 或 up。关键看两个 offset 差值是否变化:
-
master_repl_offset在主节点上持续增长(redis-cli -p 6379 info replication | grep master_repl_offset) -
slave_repl_offset在从节点上卡住不动(redis-cli -p 6380 info replication | grep slave_repl_offset) - 差值不变 → 主节点根本没把命令发出去,或从节点压根没收到
检查集群总线端口 16379 是否被防火墙/NAT/转发规则阻断
Redis 主从复制不走客户端端口(6379),而是用「集群总线端口」:主节点端口 + 10000。比如主节点监听 6379,那它对外广播和接收复制数据的端口就是 16379。这个端口一旦不通,就只有连接,没有同步。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 在从节点机器上执行:
telnet <主节点IP> 16379或nc -zv <主节点IP> 16379 - 如果失败,立刻检查三处:
- 主节点本机防火墙:
sudo iptables -L INPUT -n | grep 16379(缺规则就加:sudo iptables -I INPUT -p tcp --dport 16379 -j ACCEPT) - 云平台安全组:阿里云/AWS/GCP 的入方向规则必须显式放行
16379/tcp,且源地址填对其他节点 IP 段 - NAT 或端口转发设备:如果主节点在内网,而从节点通过公网 IP 访问,检查路由器/负载均衡器是否只转发了 6379,漏掉了 16379
- 主节点本机防火墙:
排查 Docker 或 Kubernetes 环境下的端口映射遗漏
Docker run 或 k8s Pod 配置里,常只暴露 6379,忘了加 -p 16379:16379 或 Service 的 port 定义里没包含总线端口。
- Docker 示例(错误):
docker run -p 6379:6379 redis→ 缺 16379 映射 - Docker 正确写法:
docker run -p 6379:6379 -p 16379:16379 redis - K8s Service 中必须有:
ports: - port: 6379 - port: 16379
- 验证容器内是否监听:
docker exec <container> ss -tlnp | grep ':16379'
确认主节点配置未禁用复制通道
即使端口通了,protected-mode yes 且 bind 只写 127.0.0.1 也会让主节点拒绝从节点的复制握手请求,日志里出现 Node not reachable 或反复 REPLICAOF 失败。
- 检查:
redis-cli config get protected-mode必须为no - 检查:
redis-cli config get bind不能只有127.0.0.1,至少得含内网 IP(如192.168.10.5) - 改完运行:
redis-cli config rewrite持久化,并重启从节点触发重连
偏移量不动的本质,是主节点的 repl_backlog_buffer 根本没被消费——不是缓冲区太小,而是从节点压根没连上那个“写命令管道”。端口、防火墙、NAT、容器映射、bind 配置,这五环只要断一环,就静默卡死。最容易被忽略的是:你以为在查 6379,其实该盯 16379。

















