写点什么

Redis 哨兵模式在 Spring Boot 项目中的使用与实践

作者:知识浅谈
  • 2025-09-12
    广东
  • 本文字数:2853 字

    阅读完需:约 9 分钟

Redis 哨兵模式在 Spring Boot 项目中的使用与实践

什么是 Redis 哨兵模式?

Redis Sentinel(哨兵)是 Redis 官方提供的高可用性解决方案,主要用于管理 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=mymasterspring.redis.sentinel.nodes=192.168.1.110:26379,192.168.1.111:26379,192.168.1.112:26379spring.redis.password=your-redis-password
复制代码

自定义配置类

如果需要更精细的控制,可以创建自定义配置类:


@Configurationpublic 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:


@Servicepublic 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();
复制代码


可选读策略包括:


  • MASTER:只从主节点读取

  • MASTER_PREFERRED:优先从主节点读取,主节点不可用时从副本读取

  • REPLICA:只从副本读取

  • REPLICA_PREFERRED:优先从副本读取,副本不可用时从主节点读取

常见问题与解决方案

  1. 认证失败错误:如果出现"NOAUTH HELLO must be called with the client already HELLO"错误,可能需要配置哨兵密码:


spring:  redis:    sentinel:      password: your-sentinel-password
复制代码


  1. 域名解析问题:如果哨兵返回的是域名而不是 IP,需要在本地 hosts 文件中配置域名解析。

  2. 连接池配置:根据应用需求合理配置连接池参数,以提高性能并避免资源耗尽:


lettuce:  pool:    max-active: 8    # 最大连接数    max-idle: 8      # 最大空闲连接数    min-idle: 0      # 最小空闲连接数    max-wait: 5000ms # 最大等待时间
复制代码

最佳实践

  1. 哨兵节点数量:生产环境至少部署 3 个哨兵节点,以确保哨兵集群自身的高可用性。

  2. 网络规划:尽量让应用程序节点和 Redis 节点在相同的网络环境下,减少网络延迟。

  3. 监控告警:监控 Redis 实例和哨兵进程的状态,设置适当的告警机制。

  4. 定期演练:定期进行故障转移演练,验证系统的可靠性。

  5. 客户端兼容性:确保使用的客户端版本与 Redis 服务器版本兼容。

总结

Redis 哨兵模式为 Spring Boot 应用程序提供了高可用的 Redis 解决方案,实现了自动故障转移和监控功能。通过合理的配置和使用,可以大大提升系统的稳定性和可靠性。在实际项目中,应根据业务需求选择合适的配置参数,并遵循最佳实践,才能充分发挥 Redis 哨兵模式的优势。

发布于: 刚刚阅读数: 3
用户头像

知识浅谈

关注

公众号:知识浅谈 2022-06-22 加入

🍁 作者:知识浅谈,InfoQ签约作者,CSDN博客专家/签约讲师,华为云云享专家,阿里云签约博主,51CTO专家博主 📌 擅长领域:全栈工程师、爬虫、ACM算法 💒 公众号:知识浅谈 🔥网站:vip.zsqt.cc

评论

发布
暂无评论
Redis哨兵模式在Spring Boot项目中的使用与实践_redis_知识浅谈_InfoQ写作社区