欢迎光临
我们一直在努力

RedisTemplate访问分片集群

一、前言:为什么你的 RedisTemplate 连不上集群?

你已经成功搭建了 Redis 分片集群(3 主 3 从),但在 Spring Boot 中配置 RedisTemplate 后却发现:

  • ❌ 写入时报错:(error) MOVED 12345 192.168.1.10:7002
  • ❌ 读取时连接超时
  • ❌ 多 key 操作失败:CROSSSLOT Keys in request don't hash to the same slot

根本原因:你还在用单机模式配置连接集群!

本文将手把手教你正确配置 RedisTemplate 访问 Redis Cluster,并解决常见问题。


二、核心原理:客户端如何与 Cluster 通信?

Redis Cluster 是去中心化架构:

  • 客户端首次连接任意节点
  • 节点返回 MOVED 或 ASK 重定向指令
  • 客户端缓存 <slot → node> 映射,后续直连目标节点

✅ Lettuce(Spring Boot 2.x+ 默认客户端)原生支持 Cluster 协议,自动处理重定向!


三、第一步:添加依赖(无需额外引入)

Spring Boot 2.7+ 已内置 Lettuce 和 Cluster 支持:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

⚠️ 不要手动引入 Jedis!除非你有特殊需求(Jedis Cluster 功能较弱)


四、第二步:配置 application.yml

4.1 基础配置(无密码)

spring:
redis:
cluster:
nodes:
– 192.168.1.10:7001
– 192.168.1.10:7002
– 192.168.1.10:7003
– 192.168.1.10:7004
– 192.168.1.10:7005
– 192.168.1.10:7006
timeout: 2000ms
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0

4.2 带密码的集群

spring:
redis:
password: your_cluster_password # 所有节点密码相同
cluster:
nodes: [ … ]

🔑 关键:只需列出部分节点即可(建议至少 3 个),Lettuce 会自动发现全集群拓扑。


五、第三步:配置 RedisTemplate(支持 JSON 序列化)

@Configuration
public class RedisClusterConfig {

@Bean
@Primary
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);

// 使用 Jackson 序列化,避免乱码
Jackson2JsonRedisSerializer<Object> jsonSerializer =
new Jackson2JsonRedisSerializer<>(Object.class);

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(
LaissezFaireSubTypeValidator.instance,
ObjectMapper.DefaultTyping.NON_FINAL,
JsonTypeInfo.As.PROPERTY
);
jsonSerializer.setObjectMapper(mapper);

// 设置序列化器
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(jsonSerializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jsonSerializer);
template.afterPropertiesSet();

return template;
}
}

✅ 无需自定义 RedisConnectionFactory!Spring Boot 自动创建 LettuceConnectionFactory 并启用 Cluster 模式。


六、第四步:编写业务代码(自动路由)

@Service
public class UserService {

@Autowired
private RedisTemplate<String, Object> redisTemplate;

public void saveUser(Long userId, String name) {
// 自动计算 slot 并路由到对应主节点
redisTemplate.opsForValue().set("user:" + userId, name);
}

public String getUser(Long userId) {
// 自动路由到负责该 key 的节点(主或从)
return (String) redisTemplate.opsForValue().get("user:" + userId);
}

// ⚠️ 跨 slot 多 key 操作会失败!
public List<Object> getUsers(List<Long> userIds) {
List<String> keys = userIds.stream()
.map(id -> "user:" + id)
.collect(Collectors.toList());
return redisTemplate.opsForValue().multiGet(keys); // 可能报 CROSSSLOT
}
}


七、解决常见问题

❌ 问题 1:MOVED 错误(未启用 Cluster 模式)

  • 原因:错误地使用了单机配置(如 spring.redis.host)
  • 解决:必须使用 spring.redis.cluster.nodes

❌ 问题 2:CROSSSLOT 错误

  • 原因:多个 key 不在同一 slot
  • 解决:使用 Hash Tag 强制同 slot

    // OK!{1001} 作为 hash tag
    redisTemplate.opsForValue().multiGet(
    Arrays.asList("{user1001}.name", "{user1001}.age")
    );

❌ 问题 3:客户端未刷新拓扑(扩容/故障转移后连错节点)

  • 解决:启用 Lettuce 拓扑自动刷新

    spring:
    redis:
    lettuce:
    cluster:
    refresh-period: 30s # 每 30 秒刷新一次


八、高级配置:自定义 Lettuce 行为

如需更精细控制,可自定义 LettuceClientConfiguration:

@Bean
public LettuceClientConfigurationBuilderCustomizer lettuceClientConfigurationBuilderCustomizer() {
return builder -> builder
.commandTimeout(Duration.ofSeconds(3))
.clientOptions(ClusterClientOptions.builder()
.topologyRefreshOptions(
ClusterTopologyRefreshOptions.builder()
.enablePeriodicRefresh(Duration.ofSeconds(30))
.enableAllAdaptiveRefreshTriggers() // 网络异常时主动刷新
.build())
.build());
}


九、验证是否生效

9.1 查看启动日志

INFO io.lettuce.core.cluster.RedisClusterClient –
Connecting to Redis at [192.168.1.10:7001, …]
INFO o.s.d.r.c.ClusterConnectionProvider –
Redis Cluster topology refreshed

9.2 监控 Redis 节点命令

  • 在不同 master 上执行 MONITOR
  • 观察写请求是否分布到不同节点(证明分片生效)

十、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

赞(0)
未经允许不得转载:171主机测评 » RedisTemplate访问分片集群
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址