Redis 哨兵模式在 Spring Boot 项目中的使用与实践
什么是 Redis 哨兵模式?
Redis Sentinel(哨兵)是 Redis 官方提供的高可用性解决方案,主要用于管理 Redis 主从架构,实现自动故障转移、监控和通知。在没有哨兵模式之前,当 Redis 主节点宕机时,需要手动进行主从切换并更新应用程序配置,这对运维人员来说是极大的负担。有了哨兵模式,这些操作全部自动化,对客户端透明无缝切换,大大提高了系统的可靠性。
哨兵模式主要功能包括:
Spring Boot 中配置 Redis 哨兵模式
添加依赖
在pom.xml
中添加 Spring Boot Data Redis 依赖,默认使用 Lettuce 客户端:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
复制代码
如果需要使用 Jedis 客户端,还需添加:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
复制代码
配置文件设置
在application.yml
中配置 Redis 哨兵相关信息:
spring:
redis:
password: your-redis-password # Redis认证密码
sentinel:
master: mymaster # Redis主节点名称
nodes: # 哨兵节点列表
- 192.168.1.110:26379
- 192.168.1.111:26379
- 192.168.1.112:26379
lettuce:
pool: # 连接池配置(可选)
max-active: 8
max-idle: 8
min-idle: 0
max-wait: 5000ms
复制代码
或者在application.properties
中配置:
spring.redis.sentinel.master=mymaster
spring.redis.sentinel.nodes=192.168.1.110:26379,192.168.1.111:26379,192.168.1.112:26379
spring.redis.password=your-redis-password
复制代码
自定义配置类
如果需要更精细的控制,可以创建自定义配置类:
@Configuration
public class RedisConfig {
@Value("${spring.redis.sentinel.nodes}")
private String sentinelNodes;
@Value("${spring.redis.sentinel.master}")
private String sentinelMaster;
@Bean
public RedisSentinelConfiguration redisSentinelConfiguration() {
RedisSentinelConfiguration config = new RedisSentinelConfiguration();
config.setMaster(sentinelMaster);
config.setSentinels(Arrays.stream(sentinelNodes.split(","))
.map(hostAndPort -> {
String[] args = hostAndPort.split(":");
return new RedisNode(args[0], Integer.parseInt(args[1]));
})
.collect(Collectors.toSet()));
return config;
}
@Bean
public LettuceConnectionFactory lettuceConnectionFactory(RedisSentinelConfiguration redisSentinelConfiguration) {
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.readFrom(ReadFrom.MASTER_PREFERRED) // 优先从主节点读取
.build();
return new LettuceConnectionFactory(redisSentinelConfiguration, clientConfig);
}
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(lettuceConnectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
复制代码
使用 RedisTemplate 操作 Redis
配置完成后,可以在服务中使用 RedisTemplate 来操作 Redis:
@Service
public class UserService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void saveUser(String username, String password) {
redisTemplate.opsForHash().put("users", username, password);
}
public String findUser(String username) {
return (String) redisTemplate.opsForHash().get("users", username);
}
// 更多操作方法...
}
复制代码
创建 Controller 提供 API 接口:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/add")
public String addUser(String username, String password) {
userService.saveUser(username, password);
return "用户添加成功";
}
@GetMapping("/{username}")
public String getUser(@PathVariable String username) {
return userService.findUser(username);
}
}
复制代码
读写分离配置
Lettuce 客户端支持读写分离策略,可以在配置中指定:
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.readFrom(ReadFrom.MASTER_PREFERRED) // 优先从主节点读
.build();
复制代码
可选读策略包括:
常见问题与解决方案
认证失败错误:如果出现"NOAUTH HELLO must be called with the client already HELLO"错误,可能需要配置哨兵密码:
spring:
redis:
sentinel:
password: your-sentinel-password
复制代码
域名解析问题:如果哨兵返回的是域名而不是 IP,需要在本地 hosts 文件中配置域名解析。
连接池配置:根据应用需求合理配置连接池参数,以提高性能并避免资源耗尽:
lettuce:
pool:
max-active: 8 # 最大连接数
max-idle: 8 # 最大空闲连接数
min-idle: 0 # 最小空闲连接数
max-wait: 5000ms # 最大等待时间
复制代码
最佳实践
哨兵节点数量:生产环境至少部署 3 个哨兵节点,以确保哨兵集群自身的高可用性。
网络规划:尽量让应用程序节点和 Redis 节点在相同的网络环境下,减少网络延迟。
监控告警:监控 Redis 实例和哨兵进程的状态,设置适当的告警机制。
定期演练:定期进行故障转移演练,验证系统的可靠性。
客户端兼容性:确保使用的客户端版本与 Redis 服务器版本兼容。
总结
Redis 哨兵模式为 Spring Boot 应用程序提供了高可用的 Redis 解决方案,实现了自动故障转移和监控功能。通过合理的配置和使用,可以大大提升系统的稳定性和可靠性。在实际项目中,应根据业务需求选择合适的配置参数,并遵循最佳实践,才能充分发挥 Redis 哨兵模式的优势。
评论