1,什么是redis sentinel(哨兵)
哨兵在redis集群架构中是一个非常重要的组件,其主要功能有下面这些:
- 集群监控,即时刻监控着redis的master和slave进程是否是在正常工作。
- 故障自动转移,如果redis master 节点宕机了的话,它就会将请求转到slave 节点上,slave升为master。
- 消息通知,就是说当它发现有redis实例有故障的话,就会发送消息给管理员
- 充当配置中心,如果发生了故障转移,它会通知将master的新地址写在配置中心告诉客户端。
2,需要知道的哨兵核心点
- 哨兵集群至少要 3 个节点,来确保自己的健壮性
- redis主从 + sentinel的架构,是不会保证数据的零丢失的,它是为了保证redis集群的高可用
- 你可能会问,哨兵集群 2 个节点难道就不行吗?好,如果咱们的哨兵集群只部署了两个节点,那么 quorum=1,
- 如上图,如果master宕机,sentinel 1 和 sentinel 2 只要有一个认为master宕机就会进行切换,同时sentinel 1 和sentinel 2 就会选出一个sentinel来进行故障转移,这个时候就需要用到majority(集群中一半以上,多数),即一半以上的哨兵都是运行的,但是,现在master和sentinel1运行的整个机器如果宕机了的话,那么哨兵就只有一个了,不满足一般以上的哨兵,所以也就无法进行故障转移。
3,节点sentinel架构
- 如上图所示,假设master所在的机器不可用的话,那么哨兵还剩2个,sentinel 2 和sentinel3 就会认为master宕机,然后选举一个来处理故障转移
- 三个哨兵节点的一半以上的majority为2,现在还有2个哨兵在工作着,就可以允许执行故障转移。
4,redis哨兵主备切换的数据丢失问题
- 主从异步复制导致的数据丢失:redis master 和slave 数据复制是异步的,这样就有可能会出现部分数据还没有复制到slave中,master就挂掉了,那么这部分的数据就会丢失了
- 脑裂导致的数据丢失:脑裂其实就是网络分区导致的现象,比如,我们的master机器网络突然不正常了发生了网络分区,和其他的slave机器不能正常通信了,其实master并没有挂还活着好好的呢,但是哨兵可不是吃闲饭的啊,它会认为master挂掉了啊,那么问题来了,client可能还在继续写master的呀,还没来得及更新到新的master呢,那这部分数据就会丢失。
5,解决办法
- 上面的两个数据丢失的问题,那我们该怎么去解决呢?其实也很简单,只需要在配置中加两个配置就行了,如下:
-
min-slaves-to-write 1 # 要求至少一个slave min-slaves-max-lag 10 # 数据复制和同步的延迟不能超过10s
-
解决异步复制数据的丢失:核心思想就是,一旦所有的slave节点,在数据复制和同步时延迟了超过10秒的话,那么master它就不会再接客户端的请求了,这样就会有效减少大量数据丢失的发生。
-
减少脑裂数据的丢失:
- 如果master出现了脑裂,和其他的slave失去了通信,不能继续给指定数量的slave发送数据。
- slave超过10秒没有给自己返回ack消息。
- master就会拒绝客户端的写请求
6,redis 哨兵底层核心原理深度解析
- sdown和odown转换机制
- sdown,即主观宕机,如果一个哨兵它自己觉得master宕机了,就是主观宕机
- odown,即客观宕机,如果quorum数量的哨兵都认为一个master宕机了,则为客观宕机
- 哨兵在ping一个master的时候,如果超过了is-master-down-after-milliseconds指定的毫秒数之后,就是达到了sdown,就主观认为master宕机了
- 如果一个哨兵在指定时间内,收到了quorum(法定人数)指定数量的其他哨兵也认为那个master是sdown了,那么就认为是odown了,客观认为master宕机,就完成了sdown到odown的转换。
7,哨兵集群如何实现自动发现
- 通过redis的pub/sub系统实现的,每个哨兵都会往__sentinel__:hello这个channel里发送一个消息。
- 其他哨兵可以消费到这个消息,且可以感知到其他哨兵的存在
- 每隔两秒钟,每个哨兵都会向自己监控的某个master+slaves对应的__sentinel__:hello channel里发送一个消息
- 每个哨兵也会去监听自己监控的每个master+slaves对应的__sentinel__:hello channel,然后去感知到同样在监听这个master+slaves的其他哨兵的存在
- 每个哨兵还会跟其他哨兵交换对master的监控配置,互相进行监控配置的同步。
8,slave 到master 选举算法
- 如果一个master被认为odown了,而且majority多数哨兵都允许了主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个slave来,主要通过下面几个步骤
- slave跟master断开连接的时长(断开时间越短优先级越高)
- slave优先级(在配置文件中的配置,slave priority越低,优先级就越高。)
- 复制offset(哪个slave复制了越多的数据,offset越靠后,优先级就越高。)
- run id(如果上面两个条件都相同,那么选择一个run id比较小的那个slave)
9,quorum(法定人数)和majority (大多数)关系
- 首先每一个哨兵要做主备切换的时候,首先需要quorum数量的哨兵认为odown了,然后才能从中选举出一个哨兵来做切换,其次被选举出来做切换的这个哨兵还得得到majority哨兵的授权,才能正式执行切换
- quorum法定人数的数量是在配置文件中配置的
- 举例:如果quorum < majority,比如有5个哨兵,那么一半以上的majority就是3,比如配置中quorum=2,那么就3个哨兵授权就可以执行切换
- 如果quorum >= majority,那么必须quorum数量的哨兵都授权,比如5个哨兵,quorum是5,那么必须5个哨兵都同意授权,才能执行切换。