【Redis】重学哨兵模式

这是我参与11月更文挑战的第28天,活动详情查看:2021最后一次更文挑战

一、前言

在主从库模式下:

  • 如果从库故障了,主库和其他从库仍可以保证集群正常运行。
  • 可如果主库挂了呢?

那么在主从库模式下,主库挂了会发生什么:

  1. 读操作:从库仍可以继续提供读操作服务
  2. 写操作:写操作异常(因为主库提供写操作服务)
  3. 数据同步:从库无法进行数据同步
    2021-11-2814-10-46.png

如果主库挂了,就需要选举出一个新的主库,才能继续提供正常的服务。

在这个场景下,就需要回答三个问题:

  1. 如何判断主库挂了?
  2. 选择哪个从库作为主库?
  3. 如何把主库的信息同步给其他从库和其他端?

这时候就需要另外一个机制来监控 Redis 实例:哨兵机制

那么这个哨兵机制就需要回答这三个问题:

  1. 监控:主库是否存活?
  2. 选主:在从库中选择一个成为主库。
  3. 通知:告诉其他从库,新主库的信息。

二、哨兵机制

哨兵其实一个运行在特殊模式下的 Redis 进程,主从库运行的同时,它也在运行。

如上所知,哨兵必须拥有以下三种能力:

  1. 监控:判断主从库下线
  2. 选主:选出新主库
  3. 通知:让从库执行 replicaof ,与新主库同步; 通知客户端,与新主库连接
    2021-11-2814-30-35.png

(1)监控

监控:说白就是定时去问候下,是否还活着。

即:哨兵进程在运行时,周期性给所有的主从库发送 PING 命令,检测是否正常运行。

如果没在规定时间内响应哨兵的 PING 命令:

  1. 从库:会被标记为 “下线状态”
  2. 主库:会被判定为 “主库下线”,之后开始自动切换主库流程

哨兵对主库的下线判断有:“主观下线”、“客观下线”

  • “主观下线”:哨兵发现主库或从库对 PING 命令的响应超时。
  • “客观下线”:当有 N 个哨兵实例时,有 N/2 + 1 个实例判断主库为 “主观下线”,才能最终判定主库为 “客观下线”。

如果哨兵对主库进行了误判下线,就会触发从库切换,从而带来额外的计算和通信开销。

但实际上只是集群网络压力过大、网络阻塞或者主库本身压力较大,造成短暂响应超时。

为减少误判,就不能一个哨兵说了算,得有一个哨兵集群(多实例组成),来一起进行判断:

  • 可以避免单个哨兵因为自身网络状况不好,而误判主库下线的情况
  • 多个哨兵的网络同时不稳定的概率较小

举个栗子:

  • Redis 主从集群有一个主库、三个从库、三个哨兵实例
  • 情况一(左边):哨兵2 判断主库为 “主观下线”,哨兵1 和 哨兵2 判断主库为 “上线状态”; 最终,主库仍判定为 “上线状态”。
  • 情况二(右边):哨兵3 判断主库为 “上线状态”,哨兵1 和 哨兵2 判断主库为 “主观下线”; 最终,主库仍判定为 “客观下线”。
    2021-11-2814-55-25.png

(2)选主

既然判断主库下线了,那接下来就得选主了。

选主基本流程:筛选 + 打分

  • 筛选:根据在线状态、网络状态过滤一些不符合要求的从库。
  • 打分:依次按照优先级、复制进度、ID 号大小进行打分,得分最高的从库选为新主库。
    2021-11-2815-16-43.png

筛选

筛选标准:

  1. 从库当前的在线状态:是否在线
  2. 从库之前的网络连接状态:从库和主库断连次数是否超出了一定的阈值

断连次数如何判断?使用配置项 down-after-milliseconds * 10 :

  • down-after-milliseconds:表示从库断连的最大连接超时时间
  • 10:发送断连的次数超过 10 次,说明这个从库的网络状况不好

打分

打分,可以按照三个规则进行三轮打分:

  1. 从库优先级
  2. 从库复制进度
  3. 从库 ID
第一轮:优先级最高的从库

用户可以通过 slave-priority 配置项,给不同从库设置不同优先级。

一般根据从库所在机子的配置,设置相应的权重:

  1. 如果一个从库的优先级最高,则它就是新主库了
  2. 如果从库优先级都一致,则进行第二轮打分
第二轮:和旧主库同步程度最接近

参数标准:

  • master_repl_offset:主库记录当前的最新写操作在 repl_backlog_buffer 中的位置
  • slave_repl_offset:从库记录当前的复制进度

根据以上两个参数,就可以判断从库和旧主库间的同步进度。

slave_repl_offset 越接近 master_repl_offset,得分就越高,会被选为新主库。

实际上,比较的还是 slave_repl_offset,因为旧主库宕机了,拿不到 master_repl_offset

  • master_repl_offset 会单调递增。

举个栗子:

  • 旧主库:master_repl_offset 是 1000
  • 从库 1、2和3的 slave_repl_offset:950、990 和 900
  • 则从库2 会被选为新主库
    2021-11-2815-39-34.png

如果从库的 slave_reple_offset 值大小是一样的,就需要进行第三轮打分了。

第三轮:ID 号小的从库得分高

到了决赛圈了,每个从库的 ID 号一定不同的。

Redis 在选主库时,有个默认的规定:在优先级和复制进度都相同的情况下,ID 号最小的从库得分最高,会被选为新主库。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%