Redis集群解决报错READONLY You Can't write against a read only replica
1.确保连接正确的节点
如果你使用的是 Jedis,确保你的连接字符串指向主节点。
Jedis jedis = new Jedis("master-node-address", 7004);
2.使用 Redis Sentinel 或 Cluster
如果你的 Redis 环境使用了 Sentinel 或 Cluster,客户端库通常会处理节点的发现,包括在节点故障时自动切换到新的主节点。确保你的客户端库配置正确,以便能够处理这些情况。
Set<String> sentinels = new HashSet<>();
sentinels.add("sentinel1:26379");
sentinels.add("sentinel2:26379");
JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster", sentinels);
Jedis jedis = sentinelPool.getResource();
// 执行操作
jedis.set("key", "value");
// 释放资源
jedis.close();
sentinelPool.close();
3.使用RedisTemplate
如果使用的RedisTemplate,可以对RedisTemplate进行配置
spring:
redis:
sentinel:
master: mymaster
nodes:
- sentinel1:26379
- sentinel2:26379
使用 Java 配置类来配置 RedisTemplate 和 RedisConnectionFactory。在这个配置类中,您可以指定使用 Sentinel。
@Configuration
public class RedisConfig {
@Value("${spring.redis.sentinel.master}")
private String master;
@Value("${spring.redis.sentinel.nodes}")
private String nodes;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
.master(master)
.sentinels(parseSentinelNodes(nodes));
return new JedisConnectionFactory(sentinelConfig);
}
private Set<String> parseSentinelNodes(String nodesStr) {
Set<String> nodes = new HashSet<>();
String[] nodeArray = nodesStr.split(",");
for (String node : nodeArray) {
nodes.add(node.trim());
}
return nodes;
}
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericToStringSerializer<>(Object.class));
return redisTemplate;
}
}
在您的服务或控制器中注入 RedisTemplate,并使用它来执行 Redis 操作。当 Sentinel 触发故障转移时,RedisTemplate 会自动更新其连接。