Redis哨兵集群部署与SpringBoot实战指南

2026-06-16阅读 0热度 0
其他

导航目录

主从集群配置 哨兵集群搭建 分区集群方案

实验环境

Redis版本:5.0.8 Spring Boot版本:2.2.3.RELEASE 单机版Redis安装参考:CentOS7下安装Redis(单机版) 主从部署参考:Redis集群部署及Springboot架构下应用(主从集群模式)

要实现Redis的高可用架构,哨兵机制是不可回避的核心方案。本文将完整演示从哨兵集群部署到Spring Boot项目整合的全流程,直接落地产出可运行的配置。

集群模式与基础配置

通用基础配置项如下:

后台运行(守护进程)daemonize yes 去除保护模式(允许远程访问)protected-mode no#去除绑定(远程访问)#bind 127.0.0.1# 设置密码requirepass redispwd

本次实验基于单机多端口搭建集群。如果Redis实例分布在不同机器,部分配置可省略(后续说明中会标注【单机非必须】:当前机器仅运行一个Redis实例)。

Sentinel哨兵集群部署

哨兵模式本质是一套“监控 + 投票选举”的自动故障转移机制。它解决了主从复制架构中节点宕机后人工介入的问题,相当于给主从集群配备了一个自动化运维团队。

主从配置(省略) 详细内容见:Redis集群部署及Springboot架构下应用(主从集群模式) 哨兵实例16379配置 从Redis安装目录(redis-5.0.8/sentinel.conf)复制一份配置文件,重命名为sentinel16379.conf,修改以下参数:

#哨兵服务端口,注意不能跟redis服务端口冲突,且每个哨兵端口不一样port 16379#后台运行(守护进程)daemonize yes#pid写入路径pidfile /var/run/redis-sentinel16379.pid#log目录logfile "./sentinel/16379.log"#工作目录dir ./sentinel/16379#关闭保护模式(取消该行前注释即可)protected-mode no#设置监控主节点信息(参考一下该项的配置 )sentinel monitor mymaster 192.168.1.17 6379 2#设置redis密码sentinel auth-pass mymaster redispwd

哨兵实例16380配置 复制sentinel16379.conf并重命名为sentinel16380.conf,修改如下:

#哨兵服务端口,注意不能跟redis服务端口冲突,且每个哨兵端口不一样port 16380#pid写入路径pidfile /var/run/redis-sentinel16380.pid#log目录logfile "./sentinel/16380.log"#工作目录dir ./sentinel/16380

哨兵实例16381配置 复制sentinel16379.conf并重命名为sentinel16381.conf,修改如下:

#哨兵服务端口,注意不能跟redis服务端口冲突,且每个哨兵端口不一样port 16381#pid写入路径pidfile /var/run/redis-sentinel16381.pid#log目录logfile "./sentinel/16381.log"#工作目录dir ./sentinel/16381

哨兵实例16382配置 复制sentinel16379.conf并重命名为sentinel16382.conf,修改如下:

#哨兵服务端口,注意不能跟redis服务端口冲突,且每个哨兵端口不一样port 16382#pid写入路径pidfile /var/run/redis-sentinel16382.pid#log目录logfile "./sentinel/16382.log"#工作目录dir ./sentinel/16382
关键注意事项:

配置项sentinel monitor mymaster 192.168.1.17 6379 2中的数字2代表“仲裁票数”。也就是说,至少2个哨兵判定主节点宕机时,才会触发故障转移流程。因此哨兵总数不能小于这个数值,生产环境建议部署奇数个哨兵实例以避免平票。

以下参数控制故障检测与切换行为:

#判定master节点失活时间(单位毫秒)sentinel down-after-milliseconds mymaster 30000#主备切换时,sla ve最大同时同步个数(1:即主备切换每次一个sla ve节点向master同步)sentinel parallel-syncs mymaster 1#sentinel故障转移超时时间(单位毫秒)sentinel failover-timeout mymaster 180000

192.168.1.17:主节点IP 6379:主节点端口 2 :仲裁所需的最少同意票数

启动哨兵实例

./bin/redis-sentinel sentinel16379.conf ./bin/redis-sentinel sentinel16380.conf ./bin/redis-sentinel sentinel16381.conf ./bin/redis-sentinel sentinel16382.conf

在这里插入图片描述在这里插入图片描述

执行info命令查看集群状态

在这里插入图片描述在这里插入图片描述

输出显示主节点在线、IP与端口正确、从节点数量、哨兵数量为4,一切正常。接下来模拟主节点宕机,验证自动故障转移功能。

强制终止主节点进程,观察切换过程

在这里插入图片描述在这里插入图片描述

再次查看集群状态

在这里插入图片描述在这里插入图片描述

主节点已自动切换为6381,哨兵完成了选举流程。查看新主节点详细信息:

在这里插入图片描述在这里插入图片描述

验证读写操作:

在这里插入图片描述在这里插入图片描述

从节点读写测试:

在这里插入图片描述在这里插入图片描述

重新启动被终止的原主节点,观察其状态变化

在这里插入图片描述在这里插入图片描述

在这里插入图片描述在这里插入图片描述

出现一个值得注意的现象:重启后的节点虽然正确识别了主节点信息,但并未自动加入从节点列表。查看主节点信息时,它显示的仍是从节点角色,意味着该节点无法正常接入集群工作。问题根源在哪里?

分析原因:该节点因手动kill而宕机,网络条件正常。那么它和一个全新从节点相比,缺少了什么配置?回顾主从配置参数:

#主节点地址(ip 端口)sla veof 192.168.1.17 6379#master节点密码 ,(打开注释,修改master的密码即可)masterauth redispwd

从info输出看,主节点IP和端口均正确,问题很可能出在密码配置上。原主节点配置中没有设置masterauth。补上该参数后重启节点:

在这里插入图片描述在这里插入图片描述

查看主节点状态:

在这里插入图片描述在这里插入图片描述

故障解决。这个细节提示我们:所有涉及密码的配置项必须前后一致,缺一不可,否则会破坏集群自动恢复能力。

Spring Boot集成Sentinel哨兵集群

1. 添加Maven依赖

org.springframework.bootspring-boot-starter-data-redis

2. 配置YAML文件(properties格式请自行转换)

spring:redis: # 集群(哨兵)模式sentinel:nodes:- 192.168.1.17:16379- 192.168.1.17:16380- 192.168.1.17:16381- 192.168.1.17:16382master: mymaster

3. 自定义RedisTemplate配置类 MyRedisConfig.ja va

import com.fasterxml.jackson.annotation.JsonAutoDetect;import com.fasterxml.jackson.annotation.PropertyAccessor;import com.fasterxml.jackson.databind.ObjectMapper;import org.springframework.boot.autoconfigure.data.redis.RedisProperties;import org.springframework.cache.annotation.EnableCaching;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.connection.RedisNode;import org.springframework.data.redis.connection.RedisSentinelConfiguration;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.data.redis.core.ValueOperations;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration@EnableCachingpublic class MyRedisConfig {@Bean public RedisSentinelConfiguration redisSentinelConfiguration(RedisProperties redisProperties) { RedisSentinelConfiguration configuration = new RedisSentinelConfiguration(redisProperties.getSentinel().getMaster(), new HashSet<>(redisProperties.getSentinel().getNodes())); // 实际使用中发现YAML中的密码不会自动注入到RedisSentinelConfiguration,需手动设置 configuration.setPassword(redisProperties.getPassword().toCharArray()); return configuration; } @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); // 使用Jackson2JsonRedisSerializer替换默认JDK序列化 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); // 设置Key和Value的序列化规则 redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 封装对Redis字符串类型数据的操作 * * @param stringRedisTemplate * @return */ @Bean({"valueoperations"}) public ValueOperations valueOperations(StringRedisTemplate stringRedisTemplate) { return stringRedisTemplate.opsForValue(); }}

4. 测试Controller SysController.ja va

import com.platform.test.common.exception.BusinessException;import com.platform.test.service.SysService;import com.platform.test.vo.BaseRespVo;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.data.redis.core.ValueOperations;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import ja vax.servlet.http.HttpSession;import ja va.text.SimpleDateFormat;import ja va.util.Date;import ja va.util.HashMap;import ja va.util.concurrent.TimeUnit;@RestController@RequestMapping("/sys")public class SysController { static final Logger logger = LoggerFactory.getLogger(SysController.class); @Autowired @Qualifier("valueoperations") ValueOperations valueOperations; @Autowired RedisTemplate redisTemplate; @Autowired SysService sysService; final static String REDIS_TEST_KEY_VALUE = "__REDIS_TEST_KEY_VALUE"; @RequestMapping("/health") public BaseRespVo health(HttpSession session) throws BusinessException { SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); HashMap data = new HashMap<>(); data.put("time-server", sf.format(new Date())); data.put("status-redis", checkRedis()); return new BaseRespVo(data); } private boolean checkRedis() { long time = System.currentTimeMillis(); if(valueOperations == null) { return false; } try { valueOperations.set(REDIS_TEST_KEY_VALUE time, REDIS_TEST_KEY_VALUE, 300, TimeUnit.MILLISECONDS); logger.info("写入redis key: " + REDIS_TEST_KEY_VALUE + time + " value:" + REDIS_TEST_KEY_VALUE); Thread.sleep(100); String value = valueOperations.get(REDIS_TEST_KEY_VALUE time); if (value!=null && REDIS_TEST_KEY_VALUE.equals(value)) { logger.info("读取redis key: " + REDIS_TEST_KEY_VALUE + time + " value:" + value); return true; } } catch (Exception e) { logger.error("redis test exception!", e); } return false; }}

执行结果:

在这里插入图片描述在这里插入图片描述

从节点测试:

在这里插入图片描述在这里插入图片描述

附:关键踩坑记录

在Spring Boot集成过程中,发现RedisSentinelConfiguration并不会自动从yml配置中读取密码字段,必须显式调用setPassword()方法注入。这个细节极易被忽略,导致应用启动后无法连接哨兵集群。如果有更优雅的解决方案,欢迎留言交流。

在这里插入图片描述在这里插入图片描述

补充说明: 在Sentinel模式下,无需手动跟踪每个主从节点。启动后,Redis实例的主从关系由自身配置决定,哨兵会自动从当前主节点获取集群拓扑。当监控的主节点不可达时,Sentinel根据sentinel monitor参数选举出新主节点,并自动更新自身配置文件。这才是哨兵架构的真正价值所在。

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策