《解锁Redis系列5》Redis Sentinel哨兵

觉得不错,别忘点赞!微信搜索公众号【达摩克利斯之笔】获取更多资源,文末有二维码!

一、Redis Sentinel介绍

1.1、主从复制出现的问题

上篇文章Redis主从复制中我们说到可以对Redis单节点数据进行备份实现Redis可用,但是如果master节点出现宕机情况处理起来就会非常复杂,导致节点数据不一致等问题,Redis考虑到这个问题提供了哨兵模式,也就是Redis SentinelSentinel:哨兵的意思!记住了哦,学习一个单词。

1.2、Redis Sentinel基本架构

参考下图我们说一下Redis Sentinel架构,首先我们会在集群中加入Sentinel节点,Sentinel节点会去监控Redis中Master和Slave的运行状态,判断是否可用,当然Sentinel节点也是有多个的,这样比较公平判断,不会一个Sentinel误判的情况,而且实现一个Sentinel节点的高可用,并且客户端不再直接操作Redis的Master或者Slave节点,而是去访问Sentinel节点!所以我们的客户端不在记录Redis地址,而是记录Redis Sentinel的地址!我们的客户端不关心谁是Master而是Sentinel告诉客户端谁是Master,后台Master切换了,客户端也不会受到影响!

当多个sentinel发现并确认master出现问题,会选举出一个sentinel作为领导,选举出一个slave为新的master,通知其余的slave有新的master产生,通知客户端master发生变化,等待老的master复活成为新的master的slave!

同事一套sentinel可以同时监控多套master和slave!节省资源!每套master/slave会有一个master-name作为标识以示区别

二、安装和配置

2.1、集群规划

  1. 配置开启主从节点,一个master端口号为7000,两个slave节点分别问70017002;
  2. 配置开启sentinel监控主节点。(sentinel是特殊的redis节点,不存储数据),三个sentinel分别为26379,26380,26381

2.2、配置描述

2.2.1、master

port 7000
daemonize yes
pidfile /var/run/redis/redis-7000.pid
logfile "7000.log"
dir "/usr/local/redis-5.0.5/data/"

2.2.2、slave-7001

命令:sed "s/7000/7001/g" redis-7000.conf > redis-7001.conf

将7000替换为7001

命令:echo "slaveof stt101 7000" >> redis-7001.conf

重定向slaveof stt101 7000redis-7001.conf文件末尾

port 7001
daemonize yes
pidfile /var/run/redis/redis-7001.pid
logfile "7001.log"
dir "/usr/local/redis-5.0.5/data/"
slaveof stt101 7000

2.2.3、slave-7002

port 7002
daemonize yes
pidfile /var/run/redis/redis-7002.pid
logfile "7002.log"
dir "/usr/local/redis-5.0.5/data/"
slaveof stt101 7000

 这里配置完之后启动三个节点查看主从关系redis-cli -p 7000 info replication

扫描二维码关注公众号,回复: 9303670 查看本文章

2.2.4、sentinel主要配置

#三台sentinel使用端口区别
port ${port}
dir "/usr/local/redis-5.0.5/data/"
logfile "${port}.log"
#监控主节点名字为mymaster,ip,端口,2台sentinel认为master有问题就会故障转移
sentinel monitor mymaster ip port 2
#30000毫秒ping不通认为出现问题
sentinel down-after-millisenconds mymaster 30000
#选择了新的master之后老的slave会对新的slave进行复制,1代表每次只有一个slave进行复制,减轻master压力
sentinel parallel-syncs mymaster 1
#故障转移时间
sentinel failover-timeout mymaster 180000

注意:在redis的安装目录下有一个sentinel.conf文件就是sentinel的配置文件,我们将这个文件拷贝到conf目录下,去除注释等。给出一个26739的配置,其余的两台大家只需修改端口号了pid文件即可

第一台的配置
port 26379
daemonize yes
pidfile "/var/run/redis/redis-sentinel-26379.pid"
logfile "26379.log"
dir "/usr/local/redis-5.0.5/data"
#stt101为ip映射
sentinel monitor mymaster stt101 7000 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
protected-mode no

#通过该命令将sentinel.conf文件去掉注释和换行将内容放到redis-sentinel-26739.conf文件中
cat sentinel.conf | grep -v "#" | grep -v "^$" > redis-sentinel-26739.conf
#启动
redis-sentinel redis-sentinel-26739.conf
#连接
redis-cli -p 26379
#查看信息
info
#配置其他两台
sed "s/26379/26380/g" redis-sentinel-26379.conf > redis-sentinel-26380.conf
sed "s/26379/26381/g" redis-sentinel-26379.conf > redis-sentinel-26381.conf

注意:启动三台sentinel后,配置文件会发生变化,如下图,主要是删除默认配置,指出slave节点和其他两个sentinel节点

注意:随意连接一个sentinel节点,运行info命令,截取一部分信息如下,指出slaves有2个,sentinel节点有3个。

 三、故障转移演示

3.1、客户端观察思路

我们通过Java代码操作Redis Sentinel来想Redis中存储数据,我们将Redis的Master节点干掉,查看控制台输出在客户端判断是否故障转移

3.1.1、代码实现

1、pom依赖

<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.30</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>

2、代码

package com.stt.test1;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisSentinelPool;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class RedisSentinelTest {
    //配置日志打印
    private static final Logger log = LoggerFactory.getLogger(RedisSentinelTest.class);
    
    public static void main(String[] args) {
        //master名字与配置文件中一直
        String mastername = "mymaster";
        //设置sentinel节点地址
        Set<String> sentinels = new HashSet<String>();
        sentinels.add("192.168.11.101:26379");
        sentinels.add("192.168.11.101:26380");
        sentinels.add("192.168.11.101:26381");
        //创建连接池,这里的JedisSentinelPool是为了和JedisPool做区分,获取Jedis对象也可以通过它获取
        JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(mastername, sentinels);
        while (true){
            Jedis jedis = null;
            try {
                jedis = jedisSentinelPool.getResource();
                int index = new Random().nextInt(100000);
                String key = "k-" + index;
                String value = "v-" + index;
                //设置值
                jedis.set(key,value);
                log.info("{} value is {}",key,jedis.get(key));
                //睡眠
                TimeUnit.MILLISECONDS.sleep(1000);
            }catch (Exception e){
                log.error(e.getMessage(),e);
            }finally {
                //归还jedis对象
                if(jedis != null){
                    jedis.close();
                }
            }
        }

    }
}

注意:我这里使用的是VM虚拟机上的Centos系统搭建的Redis集群,开发是在windows下完成,所以在Redis Sentine配置文件中我们之前写的是127.0.0.1代表本机,现在并不是在一台节点下做的开发,会出现连接超时问题,所以大家如果也是我这样的工作环境需要修改Redis Sentinel中的ip!

3.1.3、演示

我们关掉7000端口的redis也就是master会出现以下情况,上方是正在向Redis中国写入数据,master宕机之后,会出现无法获取Resource,连接超时等问题

当我们等待一段时间之后,这个期间并没有对集群或者代码做任何的操作,出现以下情况,我们发现又开始向Redis中写入数据,这个时间大概有2分钟左右,这个期间sentinel需要判断master是不是真的宕机了,切换等工作需要耗费时间,这个时间可以根据具体的线上业务去设置,我们上边也提到过设置时间的配置!忘记了是吧?忘记了回头再看一遍,做好笔记,哈哈!

3.2、服务端查看日志

3.2.1、数据节点日志

1、7000.log:同步数据给两个从节点,然后他就被我们kill了。

2、7001.log:从节点,连接7000节点被拒绝,之后就是成功执行配置重写

 3、7002.log:这个日志与7001类似

 我们可以登陆到7001上来看一下info发现7001被选为了master

3.2.2、sentinel节点日志

这个日志就是26379.log、26380.log和26381.log,大家有兴趣可以自己看一下!

四、三个定时任务

4.1、每10S一个info

每10秒每个sentinel节点会对master和slave发送一个info命令,一是为了发现slave节点,二是为了确认主从关系

4.2、每2秒交换信息 

每2秒每个sentinel通过master节点的channel交换信息(pub/sub),相当于一个sentinel的交互平台,交互对master/slave状态的监听情况和自身的信息。通过一个名为__sentinel__:hello的频道交互,每个sentinel节点都会订阅这个频道

4.3、每秒1ping

每一秒每个sentinel节点对其他sentinel和redis执行一次ping,这一步基于第一步sentinel掌握redis的master和slave节点的状况,基于第二步sentinel节点直到其他的sentinel节点,对他们进行心跳检测,判断是否在正常工作。


写在最后:

各位的支持和认可(点赞)是我最大的动力,请不要轻轻的来,用力留下你的足迹!

本篇文章有任何错误希望不吝指出,不胜感激!我们下篇再见!

求知并无捷径,如果有,那就是放弃这个幼稚的想法,静下心来多读书、总结

发布了23 篇原创文章 · 获赞 49 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_36386908/article/details/104331662