上一节中介绍了master-slave模式,在最小配置:master、slave各一个节点的情况下,不管是master还是slave down掉一个,“完整的”读/写功能都将受影响,这在生产环境中显然不能接受。幸好redis提供了sentinel(哨兵)机制,通过sentinel模式启动redis后,自动监控master/slave的运行状态,基本原理是:心跳机制+投票裁决

每个sentinel会向其它sentinal、master、slave定时发送消息,以确认对方是否“活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的“主观认为宕机” Subjective Down,简称SDOWN)。

若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master"彻底死亡"(即:客观上的真正down机,Objective Down,简称ODOWN),通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置。

最小化的sentinel配置文件为:

1 port 7031
2
3 dir /opt/app/redis/redis-2.8.17/tmp
4
5 sentinel monitor mymaster 10.6.144.155 7030 1
6 sentinel down-after-milliseconds mymaster 5000
7 sentinel parallel-syncs mymaster 1
8 sentinel failover-timeout mymaster 15000

第1行,指定sentinel使用的端口,不能与redis-server运行实例的端口冲突

第3行,指定工作目录

第5行,显示监控master节点10.6.144.155,master节点使用端口7030,最后一个数字表示投票需要的"最少法定人数",比如有10个sentinal哨兵都在监控某一个master节点,如果需要至少6个哨兵发现master挂掉后,才认为master真正down掉,那么这里就配置为6,最小配置1台master,1台slave,在二个机器上都启动sentinal的情况下,哨兵数只有2个,如果一台机器物理挂掉,只剩一个sentinal能发现该问题,所以这里配置成1,至于mymaster只是一个名字,可以随便起,但要保证5-8行都使用同一个名字

第6行,表示如果5s内mymaster没响应,就认为SDOWN

第8行,表示如果15秒后,mysater仍没活过来,则启动failover,从剩下的slave中选一个升级为master

第7行,表示如果master重新选出来后,其它slave节点能同时并行从新master同步缓存的台数有多少个,显然该值越大,所有slave节点完成同步切换的整体速度越快,但如果此时正好有人在访问这些slave,可能造成读取失败,影响面会更广。最保定的设置为1,只同一时间,只能有一台干这件事,这样其它slave还能继续服务,但是所有slave全部完成缓存更新同步的进程将变慢。

另:一个sentinal可同时监控多个master,只要把5-8行重复多段,加以修改即可。

具体使用步骤:(约定7030是redis-server端口,7031是redis-sentinel端口,且master、slave上的redis-server均已正常启动)

1、先在redis根目录下创建conf子目录,新建配置文件sentinel.conf,内容参考前面的内容(master和slave上都做相同的配置)

2、./redis-sentinel ../conf/sentinel.conf 即可(master和slave上都启用sentinel,即最终有二个哨兵)

3、./redis-cli -p 7031 sentinel masters 可通过该命令查看当前的master节点情况(注,这里一定要带sentinel的端口)

4、在master上,./redis-cli -p 7030 shutdown ,手动把master停掉,观察sentinel的输出

[17569] 21 Nov 11:06:56.277 # +odown master mymaster 10.6.144.155 7030 #quorum 1/1 [17569] 21 Nov 11:06:56.277 # Next failover delay: I will not start a failover before Fri Nov 21 11:07:26 2014 [17569] 21 Nov 11:06:57.389 # +config-update-from sentinel 10.6.144.156:7031 10.6.144.156 7031 @ mymaster 10.6.144.155 7030 [17569] 21 Nov 11:06:57.389 # +switch-master mymaster 10.6.144.155 7030 10.6.144.156 7030 [17569] 21 Nov 11:06:57.389 * +slave slave 10.6.53.131:7030 10.6.53.131 7030 @ mymaster 10.6.144.156 7030

从红线部分可以看出,master发生了迁移,等刚才停掉的master再重启后,可以观察到它将被当作slave加入,类似以下输出:

[36444] 21 Nov 11:11:14.540 * +convert-to-slave slave 10.6.144.155:7030 10.6.144.155 7030 @ mymaster 10.6.144.156 7030

注意事项:发生master迁移后,如果遇到运维需要,想重启所有redis,必须最先重启“新的”master节点,否则sentinel会一直找不到master。

最后,如果想停止sentinel,可输入命令./redis-cli -p 7031 shutdown

客户端的使用:

一、Jedis

 1     @Test
2 public void testJedis() throws InterruptedException {
3
4 Set<String> sentinels = new HashSet<String>();
5 sentinels.add("10.6.144.155:7031");
6 sentinels.add("10.6.144.156:7031");
7
8 JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster",
9 sentinels);
10
11 Jedis jedis = sentinelPool.getResource();
12
13 System.out.println("current Host:"
14 + sentinelPool.getCurrentHostMaster());
15
16 String key = "a";
17
18 String cacheData = jedis.get(key);
19
20 if (cacheData == null) {
21 jedis.del(key);
22 }
23
24 jedis.set(key, "aaa");// 写入
25
26 System.out.println(jedis.get(key));// 读取
27
28 System.out.println("current Host:"
29 + sentinelPool.getCurrentHostMaster());// down掉master,观察slave是否被提升为master
30
31 jedis.set(key, "bbb");// 测试新master的写入
32
33 System.out.println(jedis.get(key));// 观察读取是否正常
34
35 sentinelPool.close();
36 jedis.close();
37
38 }

4-6行是关键,这里指定了sentinel节点信息。但这段代码在运行时发现一个问题:对于1主1从的最小化配置,如果连续发生两次写操作,第1次set成功后,如果断点停在这里,down掉master,这时剩下的slave会提升为master,但是第2次set时,会抛异常,类似:连接已断开。(注:通过Spring-Data-Redis整合Jedis与redis时,利用RedisTemplate调用不会有这个问题,看来Spring-Data-Redis针对这个问题做过优化,所以建议正式项目中,通过Spring-Data-Redis整合Redis来调用相关功能,而不是自己直接引用Jedis的jar包来使用)

二、Redisson

 1     @Test
2 public void testRedisson() throws InterruptedException, ExecutionException,
3 TimeoutException {
4
5 Config config = new Config();
6
7 config.useSentinelConnection().setMasterName("mymaster")
8 .addSentinelAddress("10.6.144.155:7031", "10.6.144.156:7031");
9 config.useSentinelConnection().setRetryInterval(1000);
10 config.useSentinelConnection().setRetryAttempts(1);
11
12 Redisson redisson = Redisson.create(config);
13
14 String key = "test";
15
16 RBucket<String> myObj = redisson.getBucket(key);
17 if (myObj != null) {
18 myObj.delete();
19 }
20
21 myObj.set("aaa");// 写入
22
23 System.out.println(myObj.get());// 读取
24
25 myObj.set("bbb");// down掉master,观察是否能写入新master
26
27 System.out.println(myObj.get());
28
29 redisson.shutdown();
30
31 }

同样做类似的测试,二次写,二次读,如果第1次写后,人工down掉master,剩下的slave会提升成master,第二次写ok,但此时redis节点中,只剩master,没有slave了,从测试结果上看,第二次get还是尝试去找slave节点,但是此时已经不存在了,所以一直在等候,导致后面的的处理被阻塞。

这不是redis的问题,而是Redisson客户端设计不够智能。

鉴于这种现状,如果要使用Redisson,最好做成1主2从的部署结构:(sentinel.conf中的“法定人数”,建议调整成2)

这样的好处是,1个master挂掉后,剩下的2台slave中,会有1台提升为master,整体仍然保证有1个master和1个slave,读写均不受影响。

关于Sentinel的更多细节,可参考官网文档:http://www.redis.io/topics/sentinel

Redis-HA高可用方案Sentinel配置的更多相关文章

  1. redis HA高可用方案Sentinel和shard

    1.搭建redis-master.redis-slave以及seninel哨兵监控 在最小配置:master.slave各一个节点的情况下,不管是master还是slave down掉一个,“完整的” ...

  2. redis 学习笔记(4)-HA高可用方案Sentinel配置

    上一节中介绍了master-slave模式,在最小配置:master.slave各一个节点的情况下,不管是master还是slave down掉一个,“完整的”读/写功能都将受影响,这在生产环境中显然 ...

  3. Redis_高可用方案Sentinel配置

    最小化的sentinel配置文件为: 1 port 7031 2 3 dir /opt/app/redis/redis-2.8.17/tmp 4 5 sentinel monitor mymaster ...

  4. 深入理解Redis高可用方案-Sentinel

    Redis Sentinel是Redis的高可用方案.是Redis 2.8中正式引入的. 在之前的主从复制方案中,如果主节点出现问题,需要手动将一个从节点升级为主节点,然后将其它从节点指向新的主节点, ...

  5. Redis之高可用方案

    Redis之高可用方案   Redis以其高效的访问速度著称.但由于官方还未发布redis-cluster,而redis的replica又有诸多不便:比如一组master-slave的机器,如果之间有 ...

  6. OpenStack高可用方案及配置

    1  OpenStack高可用介绍 1.1  无状态和有状态服务 无状态服务指的是该服务接收的请求前后之间没有相关关系,接收并处理完该请求后不保存任何状态,在OpenStack的服务中常见的无状态服务 ...

  7. Redis+Keepalived高可用方案详细分析

    背景 目前,Redis集群的官方方案还处在开发测试中,未集成到稳定版中.且目前官方开发中的Redis Cluster提供的功能尚不完善(可参考官方网站或http://www.redisdoc.com/ ...

  8. 深入了解Redis(8)-高可用方案

    生产环境中的redis基本都是多节点部署,本文只讨论redis高可用的三种方案,不涉及实际操作. 一.主从复制(一主一从,一主多从,级联结构) (图来源于网络) 一个Master,两个Slave,Sl ...

  9. Redis 哨兵高可用(Sentinel)

    哨兵机制是 Redis 高可用中重要的一环,其核心是 通过高可用哨兵集群,监控主从复制的健康状态,并实现自动灾备: 哨兵集群以集群的方式进行部署,这种分布式特性具有以下优点: 避免系统中存在单点,防止 ...

随机推荐

  1. [Hbase]Hbase容灾方案

    介绍两种HBase的数据备份或者容灾方案:Snapshot,Replication: 一.Snapshot 开启快照功能,在hbase-site.xml文件中添加如下配置项: <property ...

  2. 提升HTML5的性能体验系列之三 流畅下拉刷新和上拉

    下拉刷新 为实现下拉刷新功能,大多H5框架都是通过DIV模拟下拉回弹动画,在低端android手机(Android4.4以下)上,DIV动画经常出现卡顿现象(特别是图文列表的情况).解决方案还是web ...

  3. Java设计模式(8)——策略模式

    一.策略模式定义 Strategy模式也叫策略模式是行为模式之一,它对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现,具体的算法选择交由客户 ...

  4. Roslyn研究随笔

    Roslyn概述: http://blogs.ejb.cc/archives/7604/dotnet-compile-platform-roslyn-overview 使用Microsoft Rosl ...

  5. 使用 IntelliTrace 调试应用程序

    IntelliTrace 如何能够大幅改善您的日常开发活动,并提升您快速轻松诊断问题的能力,而不必重新启动应用程序和使用传统的“中断-单步执行-检查”技术进行调试.介绍了组织如何能够通过在测试过程中收 ...

  6. oracle 大量连接导致数据库不能登录

    系统遇到过几次这种问题,一个系统申请的session数过大,导致数据库进程数满,无法连接的问题. pl sql develope 报的错误是:ORA-12170:TNS:链接超时 oracle用户登录 ...

  7. CAS 界面根据不同的域名显示不同的界面

    概要 在实际需求中,客户想通过不同的域名显示不同的登录界面,比如输入 manage.aps.cn 显示运维管理登录,business.aps.cn 显示业务管理登录. 实现方法 1.准备两套登录UI ...

  8. springboot 容器启动事件

    在springboot 容器启动时,我们需要在启动过程中做一些操作,比如启动容器后,执行某些代码. spring 提供了监听器,我们可以方便的实现这些操作. 在容器启动开始时: package com ...

  9. Codeforces Round #517 (Div. 2, based on Technocup 2019 Elimination Round 2) D. Minimum path(字典序)

    https://codeforces.com/contest/1072/problem/D 题意 给你一个n*n充满小写字母的矩阵,你可以更改任意k个格子的字符,然后输出字典序最小的从[1,1]到[n ...

  10. mysql学习之路_视图

    视图 视图:view是一种有结构的但是没有结构来源的虚拟表,虚拟表的结构来源不是自己定义的而是从对应的基表中产生(来源) 创建视图 基本语法: Create view 视图名字 as select 语 ...