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的从服务器

相关推荐
杉之19 分钟前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
morris13122 分钟前
【redis】redis实现分布式锁
数据库·redis·缓存·分布式锁
hycccccch1 小时前
Canal+RabbitMQ实现MySQL数据增量同步
java·数据库·后端·rabbitmq
bobz9651 小时前
k8s 怎么提供虚拟机更好
后端
bobz9652 小时前
nova compute 如何创建 ovs 端口
后端
用键盘当武器的秋刀鱼2 小时前
springBoot统一响应类型3.5.1版本
java·spring boot·后端
爱的叹息2 小时前
spring boot集成reids的 RedisTemplate 序列化器详细对比(官方及非官方)
redis
还是鼠鼠3 小时前
Node.js全局生效的中间件
javascript·vscode·中间件·node.js·json·express
Asthenia04123 小时前
从迷宫到公式:为 NFA 构造正规式
后端
weitinting3 小时前
Ali linux 通过yum安装redis
linux·redis