乐趣区

Redis的几个核心机制底层原理

1、S_DOWN 和 O_DOWN

  S_DOWN 和 O_DOWN 两种宕机状态

(1)、S_DOWN 是主观宕机,就一个哨兵如果自己觉得一个 master 宕机了,那么就是主观宕机

sdown 达成的条件很简单,如果一个哨兵 ping 一个 master,超过了 is-master-down-after-milliseconds 指定的毫秒数之后,就主观认为 master 宕机

# 语法:sentinel down-after-milliseconds <master-name> <milliseconds>
# Number of milliseconds the master (or any attached replica or sentinel) should
# be unreachable (as in, not acceptable reply to PING, continuously, for the
# specified period) in order to consider it in S_DOWN state (Subjectively Down).
# 意思是任何从节点或者哨兵在指定的时间内,不能 ping 通主机就被认为成 S_DOWN

(2)、O_DOWN 是客观宕机,如果 quorum 数量的哨兵都觉得一个 master 宕机了,那么就是客观宕机

 注意:S_DOWN 到 O_DOWN 转换的条件很简单,如果一个哨兵在指定时间内,收到了 quorum 指定数量的其他哨兵也认为那个 master 是 S_DOWN 了,那么就认为是 O_DOWN 了
# 语法:sentinel monitor <master-name> <ip> <redis-port> <quorum>
# Tells Sentinel to monitor this master, and to consider it in O_DOWN
# (Objectively Down) state only if at least <quorum> sentinels agree.
# 意思是:告诉 Sentinel 监视这个 master,如果至少 quorum 数量的哨兵同意的话就变成了
# 客观宕机 

2、哨兵集群的自动发现机制

  1、哨兵互相之间的发现,是通过 redis 的 pub/sub 系统实现的,每个哨兵都会往__sentinel__:hello 这个 channel 里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在。

  2、每隔两秒钟,每个哨兵都会往自己监控的某个 master+slaves 对应的__sentinel__:hello channel 里发送一个消息,内容是自己的 host、ip 和 runid 还有对这个 master 的监控配置,每个哨兵也会去监听自己监控的每个 master+slaves 对应的__sentinel__:hello channel,然后去感知到同样在监听这个 master+slaves 的其他哨兵的存在。

  3、每个哨兵还会跟其他哨兵交换对 master 的监控配置,互相进行监控配置的同步。

3、slave 配置的自动纠正

  哨兵会负责自动纠正 slave 的一些配置,比如 slave 如果要成为潜在的 master 候选人,哨兵会确保 slave 在复制现有 master 的数据; 如果 slave 连接到了一个错误的 master 上,比如故障转移之后,那么哨兵会确保它们连接到正确的 master 上

4、从机变主机的选举算法

  如果一个 master 被认为 O_DOWN 了,而且 majority 哨兵都允许了主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个 slave 来会考虑 slave 的一些信息:

(1)跟 master 断开连接的时长

(2)slave 优先级

(3)复制 offset

(4)run id

  如果一个 slave 跟 master 断开连接已经超过了 down-after-milliseconds 的 10 倍,外加 master 宕机的时长,那么 slave 就被认为不适合选举为 master

(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state

  接下来会对 slave 进行排序

(1)按照 slave 优先级进行排序,replica-priority 越低,优先级就越高,下面的英文就是这个的解释:

# The replica priority is an integer number published by Redis in the INFO output.
# It is used by Redis Sentinel in order to select a replica to promote into a
# master if the master is no longer working correctly.
#
# A replica with a low priority number is considered better for promotion, so
# for instance if there are three replicas with priority 10, 100, 25 Sentinel will
# pick the one with priority 10, that is the lowest.
#
# However a special priority of 0 marks the replica as not able to perform the
# role of master, so a replica with priority of 0 will never be selected by
# Redis Sentinel for promotion.
#
# By default the priority is 100.
replica-priority 100

(2)如果 slave priority 相同,那么看 replica offset,哪个 slave 复制了越多的数据,offset 越靠后,优先级就越高
(3)如果上面两个条件都相同,那么选择一个 run id 比较小的那个 slave

5、quorum 和 majority

  1、每次一个哨兵要做主备切换,首先需要 quorum 数量的哨兵认为 O_DOWN,然后选举出一个哨兵来做切换,这个哨兵还得得到 majority 哨兵的授权,才能正式执行切换

  2、如果 quorum < majority,比如 5 个哨兵,majority 就是 3,quorum 设置为 2,那么就 3 个哨兵授权就可以执行切换, 但是如果 quorum >= majority,那么必须 quorum 数量的哨兵都授权,比如 5 个哨兵,quorum 是 5,那么必须 5 个哨兵都同意授权,才能执行切换

6、configuration epoch

  哨兵会对一套 redis master+slave 进行监控,有相应的监控的配置

  1、执行切换的那个哨兵,会从要切换到的新 master(salve->master)那里得到一个 configuration epoch,这就是一个 version 号,每次切换的 version 号都必须是唯一的。

  2、如果第一个选举出的哨兵切换失败了,那么其他哨兵,会等待 failover-timeout 时间,然后接替继续执行切换,此时会重新获取一个新的 configuration epoch,作为新的 version 号。

7、configuraiton 传播

  1、哨兵完成切换之后,会在自己本地更新生成最新的 master 配置,然后同步给其他的哨兵,就是通过之前说的 pub/sub 消息机制

  2、version 号就很重要了,因为各种消息都是通过一个 channel 去发布和监听的,所以一个哨兵完成一次新的切换之后,新的 master 配置是跟着新的 version 号的

  3、其他的哨兵都是根据版本号的大小来更新自己的 master 配置的

帮忙关注一下 微信公众号一起学习:chengxuyuan95(不一样的程序员)

退出移动版