Redis sentinel配置
| 172.17.16.7 | 172.17.16.21 | 172.17.16.22 |
| 主 | 从 | 从 |
| php1 | mysql1 | mysql3 |
--------------------------------------------------------------------------------
主页地址:http://redis.io/topics/sentinel
第一步:搭建主从
- 搭建主从关系
- 172.17.16.7 主
- 172.17.16.21 从
- 172.17.16.22 从
- 参考上篇文章
第二步:搭建sentinel集群
sentinel主要功能就是为Redis M-S(master,slaves)集群提供了
1)master存活检测
2)集群中M-S服务监控
3) 自动故障转移,M-S角色转换等能力,
从一个方面说是提高了redis集群的可用性.
#添加并编辑配置文件/etc/sentinel.conf,新增内容如下,也可在安装文件中负责sentinel配置文件并作适当修改:
[root@php1 ~]# cat /etc/sentinel.conf
port 26379
sentinel monitor mymaster 172.17.16.7 6379 2 ---配上主的信息
sentinel auth-pass mymaster redispass
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 900000
#sentinel can-failover mymaster yes
sentinel parallel-syncs mymaster 1
[root@mysql1 ~]# cat /etc/sentinel.conf
port 26479
sentinel monitor mymaster 172.17.16.7 6379 2 ---配上主的信息
sentinel auth-pass mymaster redispass
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 900000
#sentinel can-failover mymaster yes
sentinel parallel-syncs mymaster 1
[root@mysql3 ~]# cat /etc/sentinel.conf
port 26579
sentinel monitor mymaster 172.17.16.7 6379 2 ---配上主的信息
sentinel auth-pass mymaster redispass
sentinel down-after-milliseconds mymaster 30000
sentinel failover-timeout mymaster 900000
#sentinel can-failover mymaster yes
sentinel parallel-syncs mymaster 1
#在三个服务器中以sentinel模式启动redis-server
[root@php1 ~]# redis-server /etc/sentinel.conf --sentinel
[root@mysql1 ~]# redis-server /etc/sentinel.conf --sentinel
[root@mysql3 ~]# redis-server /etc/sentinel.conf --sentinel
#最后三台服务器sentinel输出如下:(注意每个机器输出对应的都是另外两台机器的IP)
#php1
[14047] 03 Nov 10:18:55.109 * +slave slave 172.17.16.22:6379 172.17.16.22 6379 @ mymaster 172.17.16.7 6379
[14047] 03 Nov 10:18:55.109 * +slave slave 172.17.16.21:6379 172.17.16.21 6379 @ mymaster 172.17.16.7 6379
[14047] 03 Nov 10:19:42.272 * +sentinel sentinel 172.17.16.21:26479 172.17.16.21 26479 @ mymaster 172.17.16.7 6379
[14047] 03 Nov 10:20:46.338 * +sentinel sentinel 172.17.16.22:26579 172.17.16.22 26579 @ mymaster 172.17.16.7 6379
#mysql1
[3512] 03 Nov 10:23:36.473 * +slave slave 172.17.16.22:6379 172.17.16.22 6379 @ mymaster 172.17.16.7 6379
[3512] 03 Nov 10:23:36.473 * +slave slave 172.17.16.21:6379 172.17.16.21 6379 @ mymaster 172.17.16.7 6379
[3512] 03 Nov 10:23:40.446 * +sentinel sentinel 172.17.16.7:26379 172.17.16.7 26379 @ mymaster 172.17.16.7 6379
[3512] 03 Nov 10:24:45.567 * +sentinel sentinel 172.17.16.22:26579 172.17.16.22 26579 @ mymaster 172.17.16.7 6379
#mysql3
[21428] 03 Nov 10:24:40.561 * +slave slave 172.17.16.22:6379 172.17.16.22 6379 @ mymaster 172.17.16.7 6379
[21428] 03 Nov 10:24:40.561 * +slave slave 172.17.16.21:6379 172.17.16.21 6379 @ mymaster 172.17.16.7 6379
[21428] 03 Nov 10:24:41.367 * +sentinel sentinel 172.17.16.7:26379 172.17.16.7 26379 @ mymaster 172.17.16.7 6379
[21428] 03 Nov 10:24:42.280 * +sentinel sentinel 172.17.16.21:26479 172.17.16.21 26479 @ mymaster 172.17.16.7 6379
case1:关掉从的redis服务
- #关掉mysql3上的redis-server服务
- #每个sentinel将输出如下信息,表示认为slave 22已经宕机,剔除
- [3512] 03 Nov 10:30:08.359 # +sdown slave 172.17.16.22:6379 172.17.16.22 6379 @ mymaster 172.17.16.7 6379
-
- #重新启动mysql3上的redis-server服务
- #每个sentinel将输出如下信息,表示认为slave 22已经重新启动,新增到集群中
- [3512] 03 Nov 10:31:28.901 * +reboot slave 172.17.16.22:6379 172.17.16.22 6379 @ mymaster 172.17.16.7 6379
- [3512] 03 Nov 10:31:29.115 # -sdown slave 172.17.16.22:6379 172.17.16.22 6379 @ mymaster 172.17.16.7 6379
- 结果:关掉再启动可以正常剔除集群,加入集群
case2:关掉主的redis服务
Case2: 用shutdown命令停掉master,则sentinel自动选slave-priority小的那个slave进程为new master,同时,自动将另一个slave进程的master指向该new master
Case3: 在case2基础上,重启old master,sentinel会将其降级为slave,其master指向case2选出的新主 -----重启master后会出现混乱 Case4: 将master和2个slave实例的slave-priority配为互不相同的值,在Case1基础上,shutdown当前的master,在sentinel已选出新主且reconfigure其它实例使它们指向新主后(从old master异常到触发sentinel重新选主的时间由用户通过sentinel.conf的down-after-milliseconds配置项指定),重启old master,系统最终状态与Case3一致,即old master已降级为slave,其master指向sentinel选出的新主。若在sentinel已选出新主但尚未完成其它实例的reconfigure之前,重启old master,则整个系统会出现无法选出new master的异常,详情见下面Case5的描述。 ----重新选主会成功,但重启master后会出现混乱
Case5: 将master和2个slave实例的slave-priority均配为相同的值,在Case1基础上,shutdown当前的master,在sentinel已选出新主且reconfigure其它实例使它们指向新主后,重启old master,系统最终状态与Case3一致,即old master已降级为slave,其master指向sentinel选出的新主。在所有slave-priority配置为相同值的情况下,sentinel会将各slave实例中runid最小的slave提升为master(前提是该slave对应的redis.conf中允许其被promote为master)。与Case4出现的异常情况类似,若在sentinel选出新主但尚未完成其它实例的reconfigure之前,重启old master,会发现sentinel的自动故障切换机制已然凌乱了。 ----重新选主会成功,但重启master后会混乱
详细的异常情况如下所述。
old master部署在ip为xx.xx.234.67的机器上且port默认为6379,sentinel切换异常后,对该old master执行info命令输出如下:
slave-00实例在ip为xx.xx.234.49的机器上且port配为6378,sentinel切换异常后,info输出如下:
slave-01实例在ip为xx.xx.234.49的机器上(与slave-00同机部署)且port配为6377,info输出如下:
从上面3个redis实例的输出情况看,3个均认为自己是slave,整个系统无主!其中,位于xx.xx.234.67的old master(注意上面第1图的master_host字段)和位于xx.xx.234.49的salve-00(注意上面第2图的master_host字段)均认为slave-01为new master,而位于xx.xx.234.49的slave-01则认为自己仍然为slave,认为old master目前还是master(注意上面第3图的master_host字段)。
从sentinel进程日志看,其无法选出新主,即sentinel无法确认两个master candidates到底哪个是new master,在两个实例间频繁切换:
这种情况务在实际运维时务必要引起注意!
Case 6: 在系统已进入Case5所示的异常状态后,shutdown两个master candidates中的一个实例,sentinel仍然无法正常选主,直至3个实例全部shutdown,整个系统仍然无主。基本可以确定监控系统内部逻辑状态已经混乱了。
我实验很多遍的结果:关闭master 的redis服务后 会重新选取 slave-prioority小的为主(这步成功),但是只要重启master就会出现混乱的情况,除非重启master前在配置文件手工通过slaveof host ip指定主
vip故障转移:
sentinel monitor def_master 192.168.10.17 15200 2 ###主库
sentinel down-after-milliseconds def_master 3000
sentinel failover-timeout def_master 1000
sentinel client-reconfig-script def_master /home/redis/15200/sentinel/failover.sh ####vip自动切换脚本
sentinel config-epoch def_master 0
MASTER_IP=${6}
MY_IP='192.168.10.17' # 每个Server本身的IP
VIP='192.168.10.112' #vip
NETMASK='24'
INTERFACE='eno16777984' ### 接口
if [ ${MASTER_IP} = ${MY_IP} ]; then
/sbin/ip addr add ${VIP}/${NETMASK} dev ${INTERFACE}
/sbin/arping -q -c 3 -A ${VIP} -I ${INTERFACE}
exit 0
else
/sbin/ip addr del ${VIP}/${NETMASK} dev ${INTERFACE}
exit 0
fi
exit 1
开始设置redis-sentonel,只需在第一次在主库上手工设置VIP
更新:
用VIP的方式很麻烦,像ecs不支持vip怎么办呢?直接访问sentinel的端口即可,sentinel自己解决高可用的问题,只不过通过redis-cli -p 的方式读取不到罢了
/**
* 使用sentinel测试jedis连接
*/
@Test
public void testJedisSentinelPool(){
Set<String> sentinels = new HashSet<String>();
sentinels.add("sentinel1:26379");
sentinels.add("sentinel2:26380");
sentinels.add("sentinel3:26381");
JedisSentinelPool sentinelPool = new JedisSentinelPool("mymaster", sentinels);
Jedis jedis = null;
try {
jedis = sentinelPool.getResource();
int index = new Random().nextInt(10000);
String key = "k-" + index;
String value = "v-" + index;
jedis.set(key, value);
logger.info("{} value is {}", key, jedis.get(key));
TimeUnit.MILLISECONDS.sleep(100);
} catch (Exception e) {
e.printStackTrace();
} finally {
jedis.close();
}
}
附一个主从及sentinel vip模式的模板:
http://pan.baidu.com/s/1jIflboy
参考:
http://www.2cto.com/os/201505/396758.html
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29096438/viewspace-1797126/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29096438/viewspace-1797126/
本文详细介绍了Redis哨兵集群的搭建过程,包括主从关系建立、哨兵集群配置、故障转移机制及其操作流程。通过案例演示了如何在不同场景下实现Redis服务的高效容灾与故障恢复。
952

被折叠的 条评论
为什么被折叠?



