Redis Sentinel 学习笔记

  redis缓存在我们的日常编码中经常会使用到,几乎是不可或缺的一环。但如果线上的redis主服务器挂了怎么办,等待项目监控报警然让运维同学切换主备服务器来解决这个问题?当然可以,最好是把监控和主从服务器切换实现自动化,就能实现快速响应,也能减少人工的介入。redis实现了该功能,就是redis sentinel(哨兵);

 

一、sentinel是什么

  redis sentinel(哨兵)是一种redis的高可用解决方案,通过一个或者多个sentinel服务组成redis的sentinel集群,监控redis服务的状态。当被监视的redis主服务器出现问题导致下线的时候,sentinel服务则将有问题的主服务器进行降级成从服务器,将主服务器的从服务器升级为主服务器。通过这种方式,保证redis集群的高可用。

  当redis集群里的master出现宕机的时候,sentinel系统会检测到当前的master服务器已经没有响应,需要进行故障转移处理,此时sentinel系统会选出一个sentinel服务器进行以下操作

  1. 从这个master底下的服务器下slave里挑选一台成为新的主服务器
  2. sentinel会发出指令,令这个master下的其他slave服务器成为新的master服务器的slave
  3. 监视已经下线的原master,当这个master服务器重新上线时,将其设置为新的master服务器的slave

  redis sentinel服务器是一种运行在特殊模式下的redis服务器,它跟常见redis服务器的区别

  • 是两者使用不同代码,因为功能不同,默认端口因为不一样
  • sentinel启动时候不需要加载RDB文件或者AOF还原数据状态
  • 两种服务器支持的命令集不同

 

二、sentinel的状态数据

  在每一个sentinel服务启动完成之后,服务器会初始化一个sentinelState的数据结构,该结构保存了和sentinel功能有关的状态。该数据的结构如下图所示。

  sentinelState主要存储了字段包含了 current_epoch表示当前纪元,用于故障转移。还存储了master字典,保存了这个sentinel监控的所有master服务器,这个字典中key是master服务器的名字,value是一个SentinelRedisInstance的数据结构,SentinelRedisInstance表示一个master服务器、slave服务器或者sentinel服务器。

  在master服务器SentinelRedisInstance数据结构中,还保存两个字典字段,一个是salves,一个是sentinels。slaves保存着这个master对应的salves服务器。sentinels字典里存储着正在监听这个master的所有哨兵服务器。

 

三、sentinel数据同步        

   sentinel为了维持sentinelState中的数据,需要跟master和salve进行数据交互,sentinel之间也会进行数据的交换。

  1. sentinl启动时,会读取sentinel里的配置文件,获取需要监视的master服务器,为其创建一个SentinelRedisInstance数据结构,并且加入到sentinelState中。并且为该master服务器创建两个链接,分别是命令链接(用于发送命令和接收命令回复)和一个订阅链接(专门订阅_sentinel_:hello频道)
  2. sentinel会每10秒向监视的master服务器发送一次INFO命令,通过master的回复来获取相同的信息。返回信息包含master本身的信息(master本身的runId、服务器当前role )和该master的salves服务器信息(IP地址、端口、服务器状态、复制偏移量),sentinel如果发现返回salve没有保存在sentinelState里master里的salves里,就会为这个salve创建一个实例,保存到salves数据结构中,并为其创建命令链接和订阅链接。
  3. 默认情况下,sentinel会每10秒向监视的salve服务器发送INFO命令,从salve服务器中获取信息,包含服务器的run_id(运行id)、role(角色)、master_host、master_port(隶属的master服务器的IP和端口)、master_link_status(主从服务器的链接状态)、slave_priority(从服务器的优先级)和salve_repl_offset(复制偏移量),sentinel通过该信息更新salves字段中的数据信息
  4. sentinel会向以每两秒一次的频率,通过命令链接向所有被监视的主服务器和从服务器的_sentinel_:hello频道发送命令,因为监听该服务器的sentinel同时订阅_sentinel_:hello频道,所以当一个sentinel发送消息的时候,所有的sentinel能同时收到这个信息。当sentinel收到这个信息根据IP端口判断该信息由自己发送则丢弃该消息。如果不是自己发送的,则根据消息里的参数更新sentinels字段,并与其他的sentinel建立链接。通过这种方式,让sentinel感知到监听该服务器的其他sentinel,并互相之间建立命令链接。
  5. 默认情况下,sentinel会以每秒一次的频率,向所有与他创建命令链接的实例(包括主服务器、从服务器、其他的sentinel)发送PING命令来判断是否是否在线。实例会返回+PONG、-LOADING、-MASTERDOWN三种回复中的一种。

 

四、故障转移

  sentinel的故障转移分为几个步骤

1、主观下线:

sentinel配置文件中,down-after-millseconds选项指定了sentinel判断一个服务器进入主观下线的所需时间,当一个服务器超过down-after-millseconds时间之内,连续向sentinel返回无效回复或者不回复,那么sentinel会将该服务器判断为主观下线,并将数据结构中的flags属性中打开SRI_S_DOWN标识。

2、客观下线:

当一个sentinet判断一个服务器状态为主观下线后,会向监视该服务器的其他sentinel进行询问,是否其他的sentinel对该服务器的下线状态判断。当收到下线判断的数量超过了sentinel配置的quorum值,则sentinel将该服务器判断为客观下线。flags状态值改为SRI_O_DOWN

3、选举领头sentinel

当一个Master服务器被判断为客观下线之后,监视这个下线服务器的各个sentinel会进行协商,选举一个领头的sentinel进行故障转移工作。选举的方式是通过Raft算法来实现的,通过时间片分片,采用先到先得的方式获取选票,当获取的选票大于等于N/2+1时,该sentinel当选领头哨兵,对异常的Master服务器进行故障转移。

4、挑选新的master服务器

领头sentinel从salves服务器中,过滤已下线、断线状态、最近五秒没有回复INFO的回复的服务器、和已下线master断开连接超过down-after-millseconds * 10的从服务器,然后再挑选其中从服务器中配置优先级最高的服务器,如果优先级相同,则挑选复制偏移量最大的服务器,如果复制偏移量相同,则根据运行id排序,挑选id最小的从服务器作为新的master。

5、修改从服务器复制目标

设置完新的master服务器之后,领头sentinel会向其他的从服务器发送SLAVEOF命令,让其他的salve复制新的master,并将旧的master设置为新master的从服务器,等旧master服务器上线之后,就对其发送SALVEOF命令,让其复制新的Master。

 

当Master挂掉之后,客户端如何工作

  客户端来连接集群时,会首先连接 sentinel,通过 sentinel 来查询主节点的地址,然后再去连接主节点进行数据交互。当主节点发生故障时,客户端会重新向 sentinel 要地址,sentinel 会将最新的主节点地址告诉客户端。客户端连接池建立新连接时,会去查询主库地址,然后跟内存中的主库地址进行比对,如果变更了,就断开所有连接,重新使用新地址建立新连接。如果是旧的主库挂掉了,那么所有正在使用的连接都会被关闭,然后在重连时就会用上新地址。当主从库进行切换时候,客户端如果对salve发送写命令,会返回ReadOnlyError异常,当客户端获捕获到这个异常,则会将所有旧连接关闭,在后续指令里建立新的连接。

posted on 2022-06-01 18:30  阿姆斯特朗回旋炮  阅读(92)  评论(0编辑  收藏  举报

导航