【Redis】Redis sentinel配置及failover功能

Redis sentinel配置

172.17.16.7
172.17.16.21
172.17.16.22
php1 mysql1 mysql3

--------------------------------------------------------------------------------
主页地址:http://redis.io/topics/sentinel

第一步:搭建主从

  1. 搭建主从关系
  2. 172.17.16.7  主
  3. 172.17.16.21
  4. 172.17.16.22
  5. 参考上篇文章

第二步:搭建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服务

  1. #关掉mysql3上的redis-server服务
  2. #每个sentinel将输出如下信息,表示认为slave 22已经宕机,剔除
  3. [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

  4. #重新启动mysql3上的redis-server服务
  5. #每个sentinel将输出如下信息,表示认为slave 22已经重新启动,新增到集群中
  6. [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
  7. [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
  8. 结果:关掉再启动可以正常剔除集群,加入集群



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命令输出如下:
             【Redis】Redis sentinel配置及failover功能_第1张图片
        slave-00实例在ip为xx.xx.234.49的机器上且port配为6378,sentinel切换异常后,info输出如下:
             【Redis】Redis sentinel配置及failover功能_第2张图片 
        slave-01实例在ip为xx.xx.234.49的机器上(与slave-00同机部署)且port配为6377,info输出如下:
             【Redis】Redis sentinel配置及failover功能_第3张图片 
        从上面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,在两个实例间频繁切换:
【Redis】Redis sentinel配置及failover功能_第4张图片
        这种情况务在实际运维时务必要引起注意!
        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博客 ” ,链接:http://blog.itpub.net/29096438/viewspace-1797126/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29096438/viewspace-1797126/

你可能感兴趣的:(数据库,java,php)