Redis主从复制异步导致从节点数据必然滞后,READONLY仅禁写不保新;业务需“读己之写”或线性一致性时必须读主,不可依赖从节点。

主从复制不是实时同步,READONLY 不等于“读到最新数据”
Redis 主从复制默认是异步的,从节点的数据永远滞后于主节点。哪怕你执行了 READONLY 命令让客户端只连从节点,也改变不了这个事实——它只是禁止写操作,并不加速同步。常见错误现象是:主节点刚写入一个订单状态 status: "paid",紧接着在从节点查,却还是 "pending"。
- 主从之间靠
repl-backlog缓冲区 + 心跳 + 增量同步维持数据流,网络抖动或从节点阻塞(如慢查询、BGSAVE)都会拉大延迟 -
INFO replication中的master_repl_offset和从节点的slave_repl_offset差值,就是当前字节级滞后量,可用来粗略估算延迟程度 - 不要依赖
WAIT 1 100来“强制等同步”,它只作用于主节点本地的传播确认,不保证从节点已收到
哪些场景必须读主,不能碰从节点
只要业务逻辑对“读己之写”或“线性一致性”有要求,就必须绕过从节点。典型如用户刚提交表单、修改密码、支付回调后立即查余额——这些不是“最终一致”能兜住的。
- 登录态变更后立即查
user:session:{id}:从节点可能还没同步新 token 过期时间 - 库存扣减后立刻查
inventory:sku:1001:超卖风险直接来自从节点旧值 - 使用
WATCH+MULTI实现乐观锁的事务:从节点无法感知主节点上的 key 变更,EXEC失败逻辑会错乱
min-replicas-to-write 和 min-replicas-max-lag 是保命配置,但别迷信
这两个参数能防止主节点在多数从节点掉线或严重滞后时继续接受写入,属于写安全兜底,和“读不读到脏数据”没有直接关系。
-
min-replicas-to-write 2表示至少要有 2 个从节点在线才允许写;但它不检查这些从节点是否同步及时 -
min-replicas-max-lag 10表示允许最大复制延迟 10 秒,超时则主节点拒绝写入——但这个 10 秒是主节点自己根据心跳估算的,不准,且从节点实际 lag 可能远大于此 - 开启后主节点日志里出现
Rejecting write commands, since there are not enough good slaves,说明配置生效了,但这只是写入保护,不影响已有脏数据在从节点上继续存在
想“尽量少脏”,只能靠客户端控制读策略+监控 lag
Redis 本身不提供读取“已同步到 N 个从节点”的语义,所有“强一致读”都要靠应用层折中实现。
- 对关键路径,直接读主节点(用独立连接池),别试图用
SLAVEOF NO ONE临时升主——升主过程不可控,且破坏拓扑 - 如果必须读从节点,先用
ROLE或INFO replication查当前 lag,超过阈值(比如 500ms)就降级读主,别硬扛 - 在代理层(如 Redis Cluster Proxy、Twemproxy 或自研路由)做透明重试:第一次读从节点失败/超时/发现 lag 过大,自动 fallback 到主节点,但要注意幂等和缓存穿透
真正难处理的不是 lag 大小,而是 lag 的不确定性——它可能稳定在 20ms,也可能突然卡住 3 秒又恢复。所以任何基于“等待同步完成”的设计,在 Redis 主从模型下都不可靠。










