redis学习(肆) -- sentinel哨兵

一、定义

上一次我们讲过redis的主从复制存在一个很大的问题,就是主节点遇到故障只能手动恢复,而redis sentinel正是为了解决这一问题出现的。sentinel的核心功能就是通过对主从节点的监控实现及时发现主节点故障并自动故障转移的功能。sentinel实际上是特殊的redis节点,只是不存储数据。启动方式类似redis:./redis-sentinel sentinel.conf   <==指定配置文件

架构:sentinel的架构主要由客户端、哨兵节点、主从数据节点三部分组成,其中哨兵节点由一个或多个哨兵节点组成,数据节点由主从节点组成。而客户端(如jedis等)直接连接sentinel集群,通过sentinel获取redis主从节点的信息,再对reids进行操作。sentinel能够获取redis的主从运行状态,在主从遇到问题时自动做出相应处理并通知客户端使其知道哪些redis可操作。

其主要有如下几个功能:

  1. 监控:能够实时监控redis的主从是否正常工作;
  2. 通知:当被监控的节点出问题,能提醒客户端;
  3. 自动故障恢复:如果主节点宕机,sentinel将进行故障转移并通知客户端连接新master的地址。
  4. 配置提供:因为sentinel能够获取redis所有主从信息,所以客户端可通过sentinel获取对应信息。

二、sentinel的故障转移过程

  1. 在redis主从架构中,主节点宕机。
  2. 连接到该组redis的sentinel集群发现并确认master有问题,超过配置数量的sentinel觉得主节点挂了则表示真的不可用了。
  3. sentinel集群会选举出一个sentinel作为领导。
  4. 由领导从slave节点选出一个“合适的”节点做新的master节点,对其执行slaveof no one命令。
  5. 通知其它slave,更改它们master为新的master。
  6. 通知连接到sentinel的客户端(如jedis)redis主从发生了变化。
  7. 客户端重新获取redis的连接资源进行操作。
  8. 更新将原来master节点配置为slave,并保持对其关注,当其恢复后命令其复制新的master节点

说明:

(1)主观、客观下线

主观下线:表示每个sentinel节点对redis节点宕机的偏见,即一个sentinel节点“主观地”判断下线。对应的配置为 sentinel down-after-milliseconds mymaster 30000 ,即当某个sentinel节点根据定时任务的心跳检测在30秒内没有连上redis节点则其认为该redis不可用,但是有可能是网络原因只有它一个sentinel连接不上,不一定redis就真的不可用,因此才称为主观(该节点认为)下线。

客观下线:主节点才有的概念,所有sentinel节点对redis主节点不可用达成共识(超过quorun个sentinel觉得主节点不可用),对应的配置为 sentinel monitor mymaster 127.0.0.1 6379 2 ,有sentinel节点在对主节点进行主观下线后(其他节点不会有该操作),会通过sentinel is-master-down-by-addr 命令询问其他sentinel节点该主节点的状态,如果判断主节点下线的sentinel数量达到2(该值跟上面配置有关),则对该主节点进行客观下线(主节点真正不可用了)。

(2)sentinel领导选举

当sentinel集群认为主节点客观下线后,所有sentinel会选举一个领导者sentinel节点对主节点进行故障转移,选举使用的是Raft算法即先到先得,流程如下:

  1. 每个做主观下线的sentinel节点向其他sentinel节点发送 sentinel is-master-down-by-addr 命令(说明自己要成为领导者),要求将他设置为领导者
  2. 收到命令的sentinel节点如果还没有同意过其他sentinel节点发送的命令,那么就同意该请求(同意第一个请求者为领导者),否则拒绝
  3. 如果该sentinel节点发现自己的票数超过sentinel集合半数且超过quorum,那么他将成为领导者
  4. 如果此过程有多个sentinel节点成为了领导者,那么将等待一段时间重新选举。
  5. 一般来说,哨兵选择的过程很快,谁先对主节点进行客观下线,基本就是领导者。

(3)slave节点成为新master的选择方法

  1. 选择slave-priority(slave节点优先级,在配置文件,主要为了让性能好的机器先成为master)最高的slave节点,如果存在则返回,不存在则继续
  2. 选择复制偏移量最大的slave节点(复制得最完整),如果存在则返回,否则继续。
  3. 选择runId最小的slave节点。

三、sentinel的定时任务

每个哨兵(sentinel)节点维护了3个如下的定时任务:

  1. 每10秒每个sentinel对master和slave执行info,先向master发送info获取slave的节点信息,再向slave发送info获取具体信息。主要是为了发现slave节点(sentinel配置时只需配置master)、获取最新主从结构
  2. 每2秒每个 sentinel通过master节点的channel交换信息(发布订阅),每个sentinel都订阅master上的_sentinel_:hello频道,然后互相向该频道发布共享信息,包括觉得哪个节点不可用、自己的具体信息等,其作用是为了通过_sentinel_:hello频道交互对节点的看法和其他哨兵节点的信息
  3. 每1秒每个sentinel对其他sentinel和redis执行ping(基于上两步的前提下),检测对应的节点是否可用。主要是做心跳检测,作为节点是否下线的判定依据

四、客户端实现原理及java代码实现

java等客户端通过sentinel操作redis的实现原理:

  1. 客户端遍历sentinel节点集合获取一个可用的sentinel节点(找到一个就停止遍历)
  2. 将mastername发送给获取的sentinel,sentinel根据主节点名称执行 sentinel get-master-addr-by-name masterName 命令获取对应的master节点并将该节点信息返回给客户端。
  3. 客户端执行role或role replication来验证获取的是否真的为master节点
  4. 运行过程中,当sentinel集合发现redis节点发生变化时会通过发布订阅功能给客户端通知(redis节点订阅哨兵节点的+switch-master频道),客户端连接到新的master节点。

即客户端需要知道 sentinel地址集合、mastername,另外要注意客户端连接不是代理模式,最终还是直接连接到master节点进行操作,代码如下:

public static void connSentinels(){
    String masterName = "mymaster";    //对应的master节点名称
    Set<String> sentinels = new HashSet<String>();    //sentinels节点集群
    sentinels.add("192.168.1.1:26379");
    sentinels.add("192.168.1.1:26380");
    sentinels.add("192.168.1.1:26381");
    GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();//此处对poolConfig进行设置
    JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName, sentinels, poolConfig); //初始化过程做了很多工作
    Jedis jedis = null;
    try{ 
        jedis = sentinelPool .getResource(); //使用jedis进行操作,用完直接close即可,会自动判断,若单个连接则关闭,在连接池内则归还
        jedis.set("key1", "value1");
    }catch(Exception e){
    }finally{
        //close jedis
    }
}

五、配置

1、sentinel monitor {masterName} {masterIp} {masterPort} {quorum}:如 sentinel monitor mymaster 127.0.0.1 6379 2 ,这是sentinel最重要的一个配置,其中masterName为对应主节点的名称,masterIp为主节点的ip,masterPort为主节点的端口,quorum为多少sentinel觉得该主节点下线则对主节点进行客观下线,一般设置为sentinel节点数的一半加1,如上面表示至少需要2个哨兵节点同意主节点下线,才能判定主节点故障并进行故障转移。
2、sentinel down-after-milliseconds {masterName} {time}:如 sentinel down-after-milliseconds mymaster 30000,该配置与主观下线的判断有关,sentinel通过ping对其他节点进行心跳检测,当被ping节点time时间内没回复则sentinel将其进行主观下线,其对主、从节点和sentinel节点的主观下线判定都有效。可根据网络等因素调整该值,越大则主观下线判定更宽松,误判几率降低,但会导致故障发现和转移时间加长。默认值是30000,即30s。
3、sentinel parallel-syncs {masterName} {number}:如sentinel parallel-syncs mymaster 1,故障转移后需要进行主从复制,该参数规定每次向新的主节点发起复制的从节点数,上面例子表示从节点修改master之后一次只进行一次主从复制。如果故障转移新主节点切换后,有5个从节点要进行复制,则从节点会number个从节点一起复制,即一次最多number个。设置过高虽然恢复时间快,但对主节点的硬盘及网络负载较大, 默认值是1。
4、sentinel failover-timeout {masterName} {time}:如sentinel failover-timeout mymaster 180000,该配置与故障转移超时的判断有关,但是该参数不是用来判断整个故障转移阶段的超时,而是其几个子阶段的超时,例如如果主节点晋升从节点时间超过time,或从节点向新的主节点发起复制操作的时间(不包括复制数据的时间)超过time,都会导致故障转移超时失败。failover-timeout的默认值是180000,即180s;如果超时,则下一次该值会变为原来的2倍。

六、实例说明

以三个sentinel(端口:26379/26380/26381)节点,三个redis(6379/6380/6381)节点的配置如下(持久化等其他配置这里不涉及):

  1. 配置开启主从节点
  2. 配置开启sentinel监控主节点
  3. 3个哨兵节点的配置除了端口和日志等,几乎是完全一样的

(1)redis主节点配置(端口为6379)

port 6379
daemonize yes
logfile “6379.log”
dir “/home/me/redis”

(2)redis 两个从节点配置(端口为6380、6381,配置除了端口基本相同,只列一个)

port 6380
daemonize yes
logfile “6380.log”
dir “/home/me/redis”
slaveof 127.0.0.1 6379

(3)sentinel主要配置(只写出其中一个,默认配置文件为sentinel.conf)

port 26379
dir “/home/me/sentinels”
logfile “26379.log”
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

(4)通过 ./redis-sentinel sentinel.conf  启动sentinel,启动后再打开该配置文件,会看到多了从节点等信息。

(5)通过 ./redis-cli -p 26379 ,可以登录到sentinel并进行命令操作,因为其无存储,进行set操作将报错。可进行如下命令:

  • info sentinel:获取监控的所有主节点的基本信息,包括主节点个数,主节点的地址、状态,对应从节点个数,sentinel集群启动实例个数,known-slave和known-sentinel显示哨兵已经发现了从节点和其他哨兵;带有epoch的参数与配置纪元有关(配置纪元是一个从0开始的计数器,每进行一次领导者选举,都会+1。
  • sentinel masters:获取监控的所有主节点的详细信息
  • sentinel master mymaster:获取监控的主节点mymaster的详细信息
  • sentinel slaves mymaster:获取监控的主节点mymaster的从节点的详细信息
  • sentinel sentinels mymaster:获取监控的主节点mymaster的哨兵节点的详细信息
  • sentinel get-master-addr-by-name mymaster:获取监控的主节点mymaster的地址信息,前文已有介绍
  • sentinel is-master-down-by-addr:哨兵节点之间可以通过该命令询问主节点是否下线,从而对是否客观下线做出判断
  • sentinel monitor mymaster1 172.0.0.1 26380 2:增加对新主节点的监控
  • sentinel remove mymaster1:移除对主节点的监控
  • sentinel failover mymaster:由于运维等原因,如更换master机器,加内存等,需要手动下线master机器,该命令将强制对对应的主节点进行故障转移。

七、其他

(1)sentinel节点本质上是没有存储能力的redis节点。

(2)客户端初始化连接的是sentinel节点集合不是具体的redis节点,但sentinel只是配置中心不是代理。即客户端在通过sentinel获得主节点信息后,会直接建立到主节点的连接,后续的请求(如set/get)会直接发向主节点;如果是代理,客户端的每一次请求都会发向哨兵,哨兵再通过主节点处理请求。

(3)在故障转移阶段,sentinel和主从节点的配置文件都会被改写

(4)sentinel节点的数量应该是奇数,便于哨兵通过投票做出“决策”,领导者选举的决策、客观下线的决策等。

(5)sentinel是一个分布式系统,可以部署多个sentinel实例来监控同一组Redis实例,只有一个sentinel实例也可实现所有功能,只是不能对sentinel高可用。

(6)sentinel存在的问题:仍然没有解决写操作无法负载均衡、及存储能力受到单机限制的问题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值