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服务
-
参考这篇文章:http://blog.csdn.net/slvher/article/details/17682475会出现下面情况
-
Case1: 依次启动master进程及2个slave进程后,再启动2个sentinel进程,sentinel可以正常识别出主从关系
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故障转移:
-
redis-sentnel配置文件如下:
-
port 15201
-
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
脚本信息:
-
#!/bin/bash
-
-
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
-
ip addr add 192.168.10.111/24 dev eno16777984
-
更新:
用VIP的方式很麻烦,像ecs不支持vip怎么办呢?直接访问sentinel的端口即可,sentinel自己解决高可用的问题,只不过通过redis-cli -p 的方式读取不到罢了
-
比如使用Java的JedisSentinelPool连接
-
/**
-
* 使用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博客 ” ,链接:https://blog.itpub.net/29096438/viewspace-1797126/
,如需转载,请注明出处,否则将追究法律责任。