主从全量同步卡住或超时的根本原因是bgsave太慢;大内存实例bgsave耗时数分钟,导致从节点等待超时,需调大repl-timeout、关闭自动RDB或优化fork与磁盘I/O。

主从全量同步卡住或超时,根本原因是 bgsave 太慢
Redis 主从复制第一次建立连接时,主节点要执行 bgsave 生成 RDB 文件,再传给从节点。如果实例内存达 20GB+,bgsave 可能持续数分钟——期间主节点仍写入,从节点一直等不到完整 RDB,最终触发 repl-timeout 或从节点报 Connection refused。
- 检查
redis-cli -p 6379 info Persistence | grep rdb_bgsave_in_progress,若长期为1,说明bgsave已成瓶颈 -
save ""关闭自动 RDB(仅靠 AOF + 混合持久化)可跳过这步,但要求从节点启动时已有 AOF 文件且aof-use-rdb-preamble yes - 更稳妥的是调大
repl-timeout(默认 60 秒),设为300或更高,避免网络抖动误判断连
分片不是加个 Proxy 就完事,得先拆 key 空间
盲目上 Twemproxy 或 Codis 不解决根本问题:单个 Redis 实例的内存和复制压力还在。真正要做的,是把原本塞进一个实例的 key 按业务维度切开,比如按 user_id % 8 分到 8 个独立实例。
- 别用哈希标签(
{user:123})强行保一致性——它只是把相关 key 聚到同一节点,不减少单节点数据量 - 优先选「业务无状态分片」:登录态存
session:shard1:,订单存order:shard2:,各走各的集群 - 迁移期用双写 + 校验脚本,而不是依赖
redis-trib.rb这类已弃用工具;新版redis-cli --cluster rebalance只适用于 Redis Cluster 模式,不适用于纯主从分片
大内存实例开启 AOF 后 fork() 失败,得调内核参数
Linux fork() 在 Redis 中用于生成子进程做 bgsave 或 AOF rewrite。当实例 RSS 达 30GB+,而系统未配置 vm.overcommit_memory=1,fork() 会因内存不足直接失败,日志里出现 Can't save in background: fork: Cannot allocate memory。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 临时生效:
sysctl vm.overcommit_memory=1;永久写入/etc/sysctl.conf - 同时限制
auto-aof-rewrite-percentage(如设为100)和auto-aof-rewrite-min-size(如512mb),避免频繁 rewrite - 禁用
transparent_hugepage:echo never > /sys/kernel/mm/transparent_hugepage/enabled,否则 fork 延迟飙升
从节点同步延迟高,不是带宽问题,是磁盘 I/O 拖累
主节点发 RDB 是顺序写,快;但从节点接收后要解压、加载进内存,这个过程会触发大量随机读(尤其 RDB 文件大时)。如果从节点磁盘是机械盘或 IOPS 不足的云盘,loading 状态可能卡十几分钟,期间 info replication 显示 master_link_status:up 但 slave_repl_offset 几乎不动。
- 用
iostat -x 1观察从节点%util和await,若await > 50ms,基本确定是磁盘瓶颈 - 从节点务必用 SSD,且不要和其他高 IO 服务混部;云厂商的“通用型”ECS 往往配低速云盘,得手动换 IO 优化型实例
- 启用
rdb-save-incremental-fsync yes(Redis 6.0+),让 RDB 写入分块刷盘,降低单次 write 阻塞
分片本身不能消除复制风险,只是把“一次崩整个集群”变成“一次崩一个分片”。真正关键的是控制单实例内存上限(建议 ≤10GB)、确保从节点磁盘能力匹配、以及对 fork 和加载阶段做针对性调优——这些比选什么分片方案重要得多。

















