Redis主从不支持“主库只淘汰、从库只读”的高可用设计,因淘汰是各实例独立行为,不通过复制流同步,导致主从数据不一致;需靠架构层兜底,如统一路由、主库预留内存、从库禁用淘汰等。

Redis 本身不支持“主库只淘汰、从库只读”的读写分离式高可用设计——它的淘汰(eviction)是单节点行为,发生在每个实例内部,与主从角色无关。主库执行 DEL、EXPIRE 或触发 maxmemory-policy 淘汰时,从库不会同步这些内存释放动作;它只同步写命令(如 SET、INCR),而淘汰是本地决策,不走复制流。
为什么主从不能靠“分工淘汰”来提升读写可用性
主从复制只传播写操作指令,不传播内存回收行为:
-
maxmemory配置是每个 Redis 实例独立生效的,主库触发allkeys-lru淘汰时,从库仍按自己的内存压力和策略决定是否淘汰,可能保留已过期但未被访问的 key - 从库即使配置了
read_only yes,也依然会执行本地淘汰(比如自身内存超限),这会导致从库返回的数据与主库不一致(例如主库还有user:1001,从库已因 LFU 淘汰掉) - 客户端若直连从库读取,可能读到“本该存在但已被从库淘汰”的数据,造成缓存穿透或业务逻辑错乱
真正可行的高可用读写保障路径
想在内存压力下维持读写可用,得把“淘汰”和“读写路由”拆开看,靠架构层兜底:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 所有客户端统一走哨兵或 Cluster 的自动发现机制,由中间层控制流量走向,而不是手动分主/从连接
- 主库保持足够内存余量(例如
maxmemory设为物理内存的 75%),避免频繁触发淘汰影响响应延迟 - 从库必须关闭
maxmemory(设为 0)或设为远高于主库的值,防止从库自行淘汰导致数据不一致;同时开启replica-ignore-maxmemory yes(Redis 6.2+),强制从库忽略内存限制,只做数据同步 - 读请求优先打到从库,但需配合应用层降级逻辑:当从库因本地淘汰返回空时,自动回源主库或下游存储,而非直接报错
容易被忽略的淘汰副作用:过期键清理不是实时的
Redis 的过期键采用惰性删除 + 定期抽样清理,这意味着:
- 一个设置了
EXPIRE key 60的 key,在第 61 秒未必立刻消失;它可能还在内存里,直到下次被访问(触发惰性删除)或后台线程抽样到(定期删除) - 主库上已过期的 key,从库可能长期不访问,就一直留着,占用内存且影响
INFO memory统计准确性 - 如果你依赖
TTL key返回 -2 来判断 key 不存在,需注意:-2 表示 key 不存在,-1 表示存在但没设过期时间,而“存在且已过期但未清理”仍返回非负数 —— 这种状态主从可能不同步
淘汰不是高可用的解药,而是资源约束下的妥协。真正的高可用来自主从不承担不一致的职责,以及客户端对“读可能失败”有明确兜底。别指望从库替主库扛淘汰压力,它只该老老实实同步、老老实实读。

















