- 架构图
- 1.为什么需要哨兵架构
- 2.redis哨兵架构搭建
- 搭建哨兵服务
- 踩坑记录
- redis主从自动切换自动切换
- 3.Java代码连接
- 哨兵的连接代码-main方法方式-Jedis类
- Reids连接-springboot方式-RedisTemplate类
sentinel[ˈsentɪnl]哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。
哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点. 当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)。
sentinel也是redis实例;
整个哨兵集群都在监听reids的主机和所有从机,从而判断某个机器是否宕机等问题;
当哨兵发现主节点宕机,会自动选择某个从节点当做主节点;
如果没有哨兵架构,那么当主节点挂了的时候,需要运维人员手动将某个从节点设置为主节点,还需要修改IP等其他 *** 作。
2.redis哨兵架构搭建按照上面架构图来搭建架构:一个主机、两个从机、三个哨兵。
搭建一个主机两个从机
1.之前自己电脑上面已经存在6379、6380两个reids实例,且6380是作为从节点的。现在,我们再增加一个6381的从节点:
步骤:参考本篇----二、Redis主从架构1.redis主从架构搭建,配置从节点步骤
哨兵服务也是redis实例;
一般的策略是配置3个或者5个哨兵(奇数),此处我们配置三个哨兵;
1、复制一份sentinel.conf文件到我们统一的config目录下,原生的redis目录下就存在sentinel.conf cp sentinel.conf config/sentinel-26379.conf 2、将相关配置修改为如下值: port 26379 daemonize yes pidfile "/var/run/redis-sentinel-26379.pid" # 不需要创建该文件,文件会自动生成 logfile "26379.log" # 不需要创建该文件,文件会自动生成 dir "/opt/redis-6.2.2/data" # data目录是需要手动创建的,不过我们前面已经创建好了 # sentinel monitor# quorum是一个数字: #指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效 sentinel monitor mymaster 192.168.43.10 6379 2 #mymaster这个名字随便取,客户端访问时会用到 3、自己再配置两个sentinel,端口26380和26381,注意上述配置文件里的对应数字都要修改 复制命令: cp sentinel.conf sentinel-26380.conf 复制命令: cp sentinel.conf sentinel-26381.conf 修改的地方:port、pidfile、logfile、如果有sentinel myid这一行删掉(踩坑。知道为啥删吗?) 4、启动sentinel哨兵实例 src/redis-sentinel config/sentinel-26379.conf src/redis-sentinel config/sentinel-26380.conf src/redis-sentinel config/sentinel-26381.conf 5、ps -ef|grep redis查看服务是否开启 6、启动指定端口的redis服务,连接哨兵服务器。查看sentinel的info信息. src/redis-cli -p 26379 127.0.0.1:26379>info 可以看到Sentinel的info里已经识别出了redis的主从
启动三个哨兵服务:
查看哨兵服务是否开启:
sentinel集群都启动完毕后,会将哨兵集群的元数据信息写入所有sentinel的配置文件里去(追加在文件的最下面),我们查看下如下配置文件sentinel-26379.conf,如下所示:
sentinel known-replica mymaster 192.168.0.60 6380 #代表redis主节点的从节点信息 sentinel known-replica mymaster 192.168.0.60 6381 #代表redis主节点的从节点信息 #代表感知到的其它哨兵节点 sentinel known-sentinel mymaster 192.168.0.60 26380 52d0a5d70c1f90475b4fc03b6ce7c3c56935760f #代表感知到的其它哨兵节点 sentinel known-sentinel mymaster 192.168.0.60 26381 e9f530d3882f8043f76ebb8e1686438ba8bd5ca6踩坑记录
解决Redis哨兵集群哨兵之间无法感应问题
当redis主节点如果挂了,哨兵集群会重新选举出新的redis主节点,同时会修改所有sentinel节点配置文件的集群元数据信息,比如6379的redis如果挂了,假设选举出的新主节点是6380,则sentinel文件里的集群元数据信息会变成如下所示:
sentinel known-replica mymaster 192.168.0.60 6379 #代表主节点的从节点信息 sentinel known-replica mymaster 192.168.0.60 6381 #代表主节点的从节点信息 sentinel known-sentinel mymaster 192.168.0.60 26380 52d0a5d70c1f90475b4fc03b6ce7c3c56935760f #代表感知到的其它哨兵节点 sentinel known-sentinel mymaster 192.168.0.60 26381 e9f530d3882f8043f76ebb8e1686438ba8bd5ca6 #代表感知到的其它哨兵节点
同时还会修改sentinel文件里之前配置的mymaster对应的6379端口,改为6380
sentinel monitor mymaster 192.168.0.60 6380 2
当6379的redis实例再次启动时,哨兵集群根据集群元数据信息就可以将6379端口的redis节点作为从节点加入集群.。
3.Java代码连接 哨兵的连接代码-main方法方式-Jedis类该代码模拟的是:Java代码的redis客户端不会直接与redis主机连接,而是通过哨兵连接redis的主机。
public class JedisSentinelTest { public static void main(String[] args) throws IOException { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(20); config.setMaxIdle(10); config.setMinIdle(5); String masterName = "mymaster"; SetReids连接-springboot方式-RedisTemplate类sentinels = new HashSet (); sentinels.add(new HostAndPort("192.168.43.10",26379).toString()); sentinels.add(new HostAndPort("192.168.43.10",26380).toString()); sentinels.add(new HostAndPort("192.168.43.10",26381).toString()); //JedisSentinelPool其实本质跟JedisPool类似,都是与redis主节点建立的连接池 //JedisSentinelPool并不是说与sentinel建立的连接池,而是通过sentinel发现redis主节点并与其建立连接 JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, config, 3000, null); Jedis jedis = null; try { jedis = jedisSentinelPool.getResource(); System.out.println(jedis.set("sentinel", "zhuge")); System.out.println(jedis.get("sentinel")); } catch (Exception e) { e.printStackTrace(); } finally { //注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。 if (jedis != null) jedis.close(); } } }
springboot项目更多的采用RedisTemplate类连接redis,而不是采用Jedis。
哨兵的Spring Boot整合Redis连接代码见示例项目:redis-sentinel-cluster
1、引入相关依赖:
org.springframework.boot spring-boot-starter-data-redisorg.apache.commons commons-pool2
springboot项目核心配置:
server: port: 8080 spring: redis: database: 0 timeout: 3000 sentinel: #哨兵模式 master: mymaster #主服务器所在集群名称 nodes: 192.168.43.10:26379,192.168.43.10:26380,192.168.43.10:26381 lettuce: pool: max-idle: 50 min-idle: 10 max-active: 100 max-wait: 1000
访问代码:
@RestController public class IndexController { private static final Logger logger = LoggerFactory.getLogger(IndexController.class); @Autowired private StringRedisTemplate stringRedisTemplate; @RequestMapping("/test_sentinel") public void testSentinel() throws InterruptedException { int i = 1; while (true){ try { stringRedisTemplate.opsForValue().set("zhuge"+i, i+""); System.out.println("设置key:"+ "zhuge" + i); i++; Thread.sleep(1000); }catch (Exception e){ logger.error("错误:", e); } } } }
过了十几秒后,主从开始切换;
重新启动6379服务,启动6379客户端,执行info命令,发现现在redis主机成了6380,并且redis主节、从机、所有的哨兵都会自动修改同步主机配置数据(conf文件中):
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)