主从切换本身不会清空缓存,所谓“缓存清空”实为客户端连错旧主(返回READONLY)、新主未正确加载AOF/RDB、或脑裂导致旧主写入被覆盖;关键在于配置AOF+appendfsync always、成对启用min-slaves-to-write与min-slaves-max-lag、禁用从库持久化,并强制客户端校验ROLE角色。

主从切换本身不会清空缓存——Redis 的数据在从库升主后完整保留,所谓“缓存清空”其实是误判或配置不当导致的被动丢数据。
为什么你会觉得缓存被清空了
常见现象不是数据真丢了,而是客户端继续往旧地址发请求,或新主节点因配置错误没加载持久化文件:
- 客户端 DNS 缓存未刷新,仍连着已降级为从的旧主,写命令返回
READONLY被静默丢弃,业务误以为“没写进去” - 哨兵触发切换后,新主节点启动时没读取
appendonly.aof或dump.rdb(比如dir配置错、dbfilename不匹配、AOF 文件损坏) - 从库配置了
save ""和appendonly no,但主库没开 AOF,切换后新主靠 RDB 恢复——而 RDB 是定时快照,最后一次落盘之后的数据就没了
确保新主加载全量数据的关键配置
从库升主后能否恢复全部数据,完全取决于它作为从库时同步到了什么、以及自身是否能正确加载持久化文件:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 主库必须启用 AOF +
appendfsync everysec(或always),且确认aof-use-rdb-preamble yes开启(加速加载) - 从库配置中必须显式写死:
save ""(禁用 RDB)、appendonly no(禁用 AOF)、replica-read-only yes - 新主节点启动时,会按配置顺序加载:先 AOF(如果存在且完整),再 RDB;若 AOF 文件末尾损坏,Redis 会拒绝启动,需人工干预修复
- 检查
redis-server启动日志,确认出现类似DB loaded from appendonly.aof或DB loaded from disk字样,而非跳过加载
客户端连接层必须避开“假清空”陷阱
很多“缓存消失”问题出在客户端没及时感知拓扑变更,持续往只读节点发请求,看起来像数据没了:
- 不要依赖
READONLY错误做重试起点——它发生时已经失败一次,且可能掩盖真实问题(如网络分区) - 每次写操作前执行
ROLE命令,返回["slave"]就立即关闭该连接,不发业务命令 - 连接池里每个连接维护
lastRoleCheckAt时间戳,超过 30 秒未验证角色就强制重检,避免复用“过期”连接 - 用 Sentinel 时监听
+switch-master事件,收到后调用客户端 SDK 的refreshSentinels()(如 Jedis)或sentinelRefresh()(如 Lettuce)
真正要防的是脑裂期间写入被覆盖
当网络分区发生,旧主还在接收写入,而新主已选出并开始服务——这时旧主恢复后降级为从,会全量同步新主数据,导致自己刚写的那部分被覆盖。这不是“清空”,是覆盖丢失:
- 必须配
min-slaves-to-write 1+min-slaves-max-lag 10,让旧主在复制延迟超标时主动拒绝写入 - 这个组合在脑裂场景下最有效:只要旧主无法确认至少一个从节点在 10 秒内跟上,它就停写,切断脏数据源头
- 注意
min-slaves-max-lag单位是秒,不是毫秒;值设太小会导致频繁写拒绝,设太大则起不到保护作用
最容易被忽略的一点:从库升主后,它的 repl-backlog 不会自动清空,但旧主重启变从后会重新申请 backlog —— 所以 repl-backlog-size 必须全局一致且足够大,否则 PSYNC 失败降级为 FULLRESYNC,反而触发 RDB 重传和中间态丢失。

















