Redis设计与实现第16章 -- Sentinel 总结2(检查下线状态 选举领头Sentinel 故障转移)

16.6 检测主观下线状态

Sentinel会以每秒一次的频率向所有与它创建了命令连接的实例,包括主服务器、从服务器、其他Sentinel在内发送PING命令,并通过实例返回的PING命令回复来判断实例是否在线。

配置文件的down-after-millseconds选项指定了Sentinel判断实例进入主观下线所需要的时间长度:如果一个实例在down-after-millseconds毫秒内连续向Sentinel返回无效回复,那么Sentinel会修改这个实例所对应的实例结构,在结构的flags属性中打开SRI_S_DOWN标识,以此表示这个实例已进入主观下线状态

多个Sentinel设置的主观下线时长也可以不同

16.7 检查客观下线状态

当Sentinel将这一主服务器判断为主观下线后,为了确认这个主服务器是否真的下线,它会向同样监视这一主服务器的其他Sentinel进行询问,看他们是否也认为主服务器已经进入了下线状态(可以是主观下线,也可以是客观下线),当收到足够数量的已下线判断之后,Sentinel就会将主服务器判定为客观下线,并进行故障转移操作

16.7.1 发送Sentinel命令

发送SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid> 命令,询问其他Sentinel是否同意主服务器已下线。

其中current_epoch 表示Sentinel当前的配置纪元,用于选举领头Sentinel;runid可以是*或是Sentinel的运行ID,*表示检测主服务器的客观下线,Sentinel的运行ID用于选举领头Sentinel

16.7.3 接收Sentinel命令

当目标Sentinel收到源Sentinel发来的SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <runid> 命令时,目标Sentinel会分析并取出命令请求里包含的各个参数,并根据其中的主服务器的IP和端口号,检查是否下线。然后向源Sentinel返回一条包含三个参数的Multi Bulk回复作为SENTINEL is-master-down-by命令的回复。

  1. <down_state> 返回目标Sentinel对主服务器的检查结果,1表示主服务器已下线,0表示主服务器未下线

  2. <leader_runid>可以是*符号或是目标Sentinel的局部领导Sentinel的运行ID

  3. <leader_eopch> 目标Sentinel的局部领头Sentinel的配置纪元,用于选举领头Sentinel

16.7.3 接受回复

Sentinel会统计其他Sentinel同意主服务器已下线的数量,当这一数量达到配置指定的判断客观下线所需要的数量时,Sentinel会将主服务器实例结构属性的SRI_O_DOWN标识打开,表示主服务器已经进入客观下线状态。

16.8 选举领头Sentinel

当一个主服务器被判断为客观下线时,监视这个下线主服务器的各个Sentinel会进行协商,选举出一个领头Sentinel,并由领头Sentinel对下线主服务器执行故障转移操作。

Redis选举领头Sentinel的规则和方法:

  1. 所有在线的Sentinel都有被选为领头Sentinel的资格

  2. 每次进行选举以后,不论是否成功,所有Sentinel的配置纪元的值都会自增一次

  3. 在一个配置纪元里面,所有Sentinel都有一次将某个Sentinel设置为局部领头Sentinel的机会,一旦设置,在这个配置纪元里就不能在更改。

  4. 每个发现主服务器进行客观下线的Sentinel都会要求其他Sentinel将自己设置为局部领头Sentinel

  5. 当源Sentinel向目标Sentinel发送SENTINEL is-master-down-by-addr命令,并且命令中的runid参数不是*而是源Sentinel的运行ID时,表示源Sentinel要求目标Sentinel将源Sentinel设置为目标Sentinel的局部领头Sentinel

  6. Sentinel设置局部领头Sentinel的规则是先到先得

  7. 目标Sentinel在接收到SENTINEL is-master-down-by-addr命令后,向源Sentinel返回一条命令回复,回复里的的leader_runid/leader_epoch参数分别记录了目标Sentinel的局部领头Sentinel的运行ID和配置纪元

  8. 源Sentinel在接收到目标Sentinel返回的命令回复之后,会检查回复中leader_epoch参数的值和自己的配置纪元是否相同;相同的话,会继续取出回复的leader_runid参数,如果该值和源Sentinel的运行ID一致,表示目标Sentinel将源Sentinel设置成了局部领头Sentinel

  9. 如果某个Sentinel被半数以上的Sentinel设置为了局部领头Sentinel,这个Sentinel称为领头Sentinel。

  10. 如果给定时间里,没有一个Sentinel被选举为领头Sentinel,各个Sentinel将在一段时间之后再次进行选举,直到选出为止。

16.9 故障转移

  1. 在已下线主服务器属下的所有从服务器里面,挑选出一个从服务器,并将其转换为主服务器

  2. 让已下线主服务器属下的所有从服务器都改为复制新的主服务器

  3. 将已下线主服务器设置为新的主服务器的从服务器

16.9.1 选出新的主服务器

选出一个状态完整、数据完整的从服务器,然后向这个从服务器发送SLAVEOF no one命令,将从服务器转为主服务器。

  1. 删除列表里所有下线或是断线的从服务器,保证正常在线

  2. 删除列表里最近五秒内没有回复过领头Sentinel的INFO命令的从服务器,保证最近成功通信

  3. 删除所有与已下线服务器连接断开超过down-after-millseconds*10ms的从服务器,保证数据较新

  4. 先选优先级最高,再选复制偏移量最大,再选运行ID最小

发送后,领头Sentinel会以每秒一次的频率向被升级的从服务器发送INFO命令,并观察命令回复中的角色role信息。

16.9.2 修改从服务器的复制目标

向从服务器发送SLAVEOF 命令来实现,让其他从服务器去复制新的主服务器

16.9.3 将旧的主服务器变为从服务器

当server1重新上线时,Sentinel会发送SLAVEOF命令,让它称为server2的从服务器

相关推荐
丁卯40410 分钟前
Go语言中使用viper绑定结构体和yaml文件信息时,标签的使用
服务器·后端·golang
希忘auto2 小时前
详解Redis在Centos上的安装
redis·centos
roman_日积跬步-终至千里3 小时前
【分布式理论16】分布式调度2:资源划分和调度策略
分布式
ITPUB-微风3 小时前
Service Mesh在爱奇艺的落地实践:架构、运维与扩展
运维·架构·service_mesh
bing_1584 小时前
简单工厂模式 (Simple Factory Pattern) 在Spring Boot 中的应用
spring boot·后端·简单工厂模式
天上掉下来个程小白4 小时前
案例-14.文件上传-简介
数据库·spring boot·后端·mybatis·状态模式
Asthenia04125 小时前
基于Jackson注解的JSON工具封装与Redis集成实战
后端
编程星空5 小时前
css主题色修改后会多出一个css吗?css怎么定义变量?
开发语言·后端·rust
程序员侠客行6 小时前
Spring事务原理 二
java·后端·spring
dmy6 小时前
docker 快速构建开发环境
后端·docker·容器