psync2能在主节点故障切换后继续部分同步,前提是新主正确继承旧主的master_replid2和second_repl_offset,并且repl-backlog足够大以覆盖断连期间的数据;否则仍会退化为全量同步。

PSYNC2 能否在主节点故障切换后继续部分同步
能,但前提是主节点(新主)保留了旧主的 master_replid2 和对应偏移量 second_repl_offset。PSYNC2 不再绑定单一 run_id,而是用双 replication ID 机制:当前 master_replid + 上一个主的 master_replid2。当 Sentinel 或 Cluster 提升从节点为新主时,它会把原主的 master_replid 写入自己的 master_replid2,并继承其 second_repl_offset。这样,其他从节点重连时发 PSYNC <old_replid><offset></offset></old_replid>,新主就能查 backlog 是否覆盖该 offset。
常见失效场景包括:
- 新主未正确继承
master_replid2(如手动replicaof no one后未做DEBUG RELOAD) - 旧主已宕机过久,
repl-backlog-ttl(默认 3600 秒)超时导致 backlog 被释放 - 从节点保存的 offset 已超出新主 backlog 范围——此时即使协议支持,也无数据可补
如何确认当前连接走的是 PSYNC2 部分同步
别信 INFO replication 里显示的 master_replid 和 master_repl_offset,它们只反映状态,不反映本次同步类型。真正判断依据只有两个:
- 主节点日志中出现
"Partial resynchronization request accepted"—— 这是 PSYNC2 成功响应的唯一铁证 - 从节点执行
ROLE,返回数组第二项为"stable_sync"(不是"connect"或"loading")
如果看到 "Full resync requested by slave" 或 "Starting BGSAVE for SYNC",说明已退化为全量,得立刻查 repl-backlog-size 和网络断连时长。
repl-backlog-size 配多大才不算瞎配
不是按“内存剩多少”来配,而是按“峰值写入带宽 × 最大容忍断连时间”算。例如:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 主节点平均写入速率 60 MB/s,跨机房链路最大抖动 500ms → 理论需至少 60 × 0.5 = 30 MB
- 再加 50% 冗余 → 建议设为
repl-backlog-size 48mb - 若用默认 1MB,在断连 200ms 后就大概率丢数据,PSYNC2 直接失效
注意:repl-backlog-size 是环形缓冲区上限,Redis 7.0 虽支持动态扩(检测将满时自动增长),但上限仍卡死在这个配置值。配小了,动态扩也没用。
为什么 DEBUG RELOAD 有时比 replicaof 更管用
replicaof no one && replicaof <new_master></new_master> 只是重置连接状态,不会清空从节点本地记录的旧 master_replid 和 slave_repl_offset,重连时仍可能发错 PSYNC 请求。而 DEBUG RELOAD(仅限开发/测试环境)会强制从节点丢弃所有复制元信息,重启后以空状态发起首次同步,从而确保它带上正确的 replid 和 offset 去匹配新主的 backlog。
生产环境不能依赖这个命令,但理解它能帮你定位问题:当从节点长期离线、master_replid2 已失效、又无法接受全量同步时,真正可控的路径只有一条——先调大 repl-backlog-size,再让从节点短暂下线清理状态,而非反复切主从。
PSYNC2 不是魔法,它只在 backlog 有数据、replid 可追溯、offset 未越界这三点同时满足时才生效。缺一不可,而最容易被忽略的是 backlog 大小与实际写入节奏的匹配关系。










