必须显式声明read-from策略,否则所有读写请求默认全走主节点;推荐生产使用replica_preferred,优先读从节点,从节点不可用时自动降级读主节点。

read-from 配置项必须显式声明,否则默认全走主节点
Spring Boot 的 spring.redis.host 和 spring.redis.port 只支持单节点地址,即使你写成 192.168.1.10:6379,192.168.1.11:6379,Lettuce 也不会自动识别主从拓扑——它只把这当作故障转移候选列表,所有读写请求仍发往主节点。真正触发读写分离的是 read-from 策略,且必须在配置中明确指定。
常见错误现象:@Cacheable 方法、StringRedisTemplate.opsForValue().get()、redisTemplate.hasKey() 全部打到主节点,从节点 CPU/网络零负载;监控发现主节点连接数高、延迟上升,而从节点闲置。
-
read-from不是连接建立时静态绑定的,而是在每次执行sync()或async()时动态选节点 - 该配置对
RedisTemplate、@Cacheable、ReactiveRedisTemplate全局生效 - 若使用哨兵模式,
read-from必须配合spring.redis.sentinel.nodes和spring.redis.sentinel.master才能正确识别从节点
application.yml 中正确配置 REPLICA_PREFERRED
这是生产环境最稳妥的选择:读优先走从节点,任一从节点可用即路由过去;所有从节点均不可用时,自动降级读主节点,保障可用性。注意大小写和拼写——Lettuce 3.2+ 使用 REPLICA_PREFERRED(不是 SLAVE_PREFERRED),旧版本才用后者。
正确配置示例(哨兵模式):
spring:
redis:
sentinel:
nodes: 192.168.1.10:26379,192.168.1.11:26379
master: mymaster
lettuce:
pool:
max-active: 32
# 关键:必须在此层级下配置 read-from
read-from: REPLICA_PREFERRED
- 不要写在
spring.redis.lettuce.cluster下(那是集群模式专用) - 不要漏掉
sentinel块,否则 Lettuce 无法获取主从拓扑信息 - 如果用主从直连(非哨兵),需改用
spring.redis.cluster.nodes并确保节点列表包含主+所有从
自定义 LettuceClientConfigurationBuilderCustomizer 更灵活
当需要运行时动态切换策略(比如按 IDC 区分:深圳机房读从、北京机房读主),就不能只靠 yml 静态配置,得用代码干预客户端构建过程。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
推荐写法(Spring Boot 3.2+):
@Bean
public LettuceClientConfigurationBuilderCustomizer configurationBuilderCustomizer() {
return configBuilder -> configBuilder.readFrom(ReadFrom.REPLICA_PREFERRED);
}
- 这个 Bean 会自动被
LettuceConnectionConfiguration拦截并应用 - 可结合
@Value("${app.idc}")实现条件化策略,比如idc.equals("sz") ? ReadFrom.REPLICA_PREFERRED : ReadFrom.MASTER - 避免重写整个
RedisConnectionFactoryBean,否则会绕过 Spring Boot 自动配置的连接池、超时等默认设置
容易忽略的一致性风险与验证方式
启用 REPLICA_PREFERRED 后,读操作可能返回旧数据——因为 Redis 主从复制是异步的,从节点存在秒级延迟。这不是 bug,而是设计取舍。
验证是否真生效,别只看日志或配置文件:
- 在从节点执行
redis-cli -p 6380 monitor,同时调用一个redisTemplate.opsForValue().get("key"),观察命令是否出现在从节点的 monitor 输出里 - 用
INFO replication查看从节点的master_last_io_seconds_ago,确认复制延迟在合理范围(通常 - 如果业务要求强一致性读(如支付结果页),应显式用
RedisTemplate.setEnableTransactionSupport(true)+multi(),或临时切换为ReadFrom.MASTER
最终效果取决于拓扑发现是否成功、从节点健康状态、以及你的读操作是否真的被 Lettuce 判定为“可读从”。任何一环断开,都会静默回退到主节点——这点既保证了可用性,也掩盖了配置失效的问题。










