必须显式配置read-from,否则所有读写请求默认全走主节点;推荐生产使用REPLICA_PREFERRED,优先读从节点,从节点不可用时自动降级读主节点。
Spring Boot 默认不启用读写分离,spring.redis.host 和 spring.redis.port 只能指向单节点,即使你写成逗号分隔的多个地址,Lettuce 也只当它是故障转移候选列表,不会自动识别主从拓扑。所有 @Cacheable、redisTemplate.opsForValue().get()、redisTemplate.hasKey() 都会发往主节点——监控里能看到主节点连接数高、延迟涨,而从节点 CPU/网络几乎为零。
必须在配置中明确声明 read-from 策略,且位置不能错:
spring.redis.lettuce.read-from(不是 spring.redis.lettuce.cluster.read-from)spring.redis.cluster.nodes 列出主+所有从节点REPLICA_PREFERRED(Lettuce 3.2+),旧版本才用 SLAVE_PREFERRED
仅配 spring.redis.sentinel.nodes 不够,spring.redis.sentinel.master 必须与哨兵配置文件 sentinel.conf 中 sentinel monitor 后的名称完全一致,否则 Lettuce 无法拉取主从拓扑信息,read-from 就是空转。
常见错误包括:
nodes,实际该填哨兵节点地址(如 26379 端口)sentinel 块,导致 Lettuce 退化为单节点直连行为spring.redis.sentinel.password,数据节点密码走 spring.redis.password
read-from 策略在每次调用 sync() 或 async() 时才触发节点选择,这意味着:
RedisTemplate、@Cacheable、ReactiveRedisTemplate 全局生效,无需额外适配REPLICA_PREFERRED 是优先读从,所有从节点都不可用时自动降级读主,保障可用性LettuceClientConfigurationBuilderCustomizer 在代码里干预客户端构建过程,yml 静态配置做不到Redis 主从复制是异步的,REPLICA_PREFERRED 下的读操作可能读到几毫秒甚至几百毫秒前的数据。这不是配置问题,而是架构限制。
业务上需接受最终一致性,并注意:
set("user:1001", "xxx") 后立刻 get("user:1001"),结果可能为空或旧值RedisTemplate.getConnectionFactory().getConnection().read(ReadFrom.MASTER) 临时覆盖策略INFO replication 中的 master_repl_offset 和各从节点 slave_repl_offset 差值,评估延迟水位