Zookeeper和Redis中的选举工作

前言

最近在准备复习了,想着把以前的知识串一串,零零散散的总是很容易忘,知识还是要成体系的,这也是互联网工程师的必备素养吧,要不每天都有新知识,等到35还怎么和年轻人拼,只有沉淀出自己的东西,才能不被淘汰。

现在到处都是分布式、高并发,我们用的很多东西像数据库之类的到了生产环境都会是集群部署,每台机器都是一个节点,很多场景又会分为主从节点,比如主写从读啊之类的,当然,说到这里少不了节点挂了的情况,节点挂了一般问题也不大,现在故障转移各种工作已经做的很到位了,毕竟要保证高可用嘛。今天就来唠一下,节点挂了后一些相关的选举工作,本文主要以 ZookeeperRedis 为例来说明。

Redis选举领头Sentinel

Sentinel是Redis实现高可用的保证。Sentinel系统作用就是监视Redis服务器集群,它可以不停的获得redis集群状态,当一个主节点挂了,故障转移操作会在从节点中选出一个新的主节点,这里故障转移就是由Sentinel来主导完成的。

不要把Sentinel想的太复杂,它其实就是一个特殊工作模式的Redis服务器而已,Redis是集群部署的,这里的Sentinel也是要集群部署的,要是非单点部署,你的Sentinel挂了,此时的Redis集群就GG了。

接着上边说,当主服务器节点挂了,Sentinel系统就会选出一个领头的Sentinel来完成故障转移工作。选举规则如下:

  • 监视这个挂了的主节点的所有Sentinel都有被选举为领头的资格

  • 每进行一次选举,不论是否成功,配置纪元+1,配置纪元就是个计数器

  • 每个Sentinel在每个配置纪元中有且仅有一次选举机会,一旦选好了该节点认为的主节点,在这个纪元内,不可以再更改

  • 每个发现服务器挂了的Sentinel都会配置纪元+1并投自己一票,接着发消息要求其他Sentinel设置自己为领头人1,每个Sentinel都想成为领头的

  • 每个Sentinel会将最先发来请求领头的节点设为自己的领头节点并发送回复,谁先来我选谁

  • 当源Sentinel收到回复,并且回复中的配置纪元和自己的一致且领头Id是自己的Sentinel Id时,表明目标Sentinel已经将自己设为领头

  • 在一个配置纪元内,当某个Sentinel收到半数以上的同意回复时,它就是领头的了

  • 如果在给定时间内,没有被成功选举的Sentinel,那么过段时间发起新的选举

选举领头Sentinel的过程和规则大概就如上所述,需要注意的是只有集群出现节点挂了才需要选举出领头Sentinel,平时每个Sentinel还是平等身份~

这里的选举其实是raft算法的一个应用,有兴趣的小伙伴可以去读下这篇算法的论文

Zookeeper选举

Zookeeper是一个很强的分布式数据一致性解决方案,比如dubbo中的注册中心就使用的Zookeeper。当然,这也是集群部署的,但是它没有采用传统的Master/Slave结构,而是引入了Leader、Follwer和Observer。Leader和Follower类似于Master/Slave,新增的Observer作用仅仅只是增加集群的读性能,它不参与Leader的选举。

节点的状态有以下几种:

  • LOOKING: 节点正处于选主状态,不对外提供服务,直至选主结束;

  • FOLLOWING: 作为系统的从节点,接受主节点的更新并写入本地日志;

  • LEADING: 作为系统主节点,接受客户端更新,写入本地日志并复制到从节点

Zookeeper的状态同步是基于Zab协议实现的,Zab协议有两种模式,它们分别是崩溃恢复(选主)和消息广播(同步)。当服务启动或者在Leader崩溃后,Zab就进入了恢复模式,当Leader被选举出来,且超过一半机器完成了和 leader的状态同步以后,恢复模式就结束了。

我们来重点看下选主是怎么完成的

首先明确几个概念:

  • Sid:服务器id;

  • Zxid:服务器的事务id,数据越新,zxid越大;zxid的高32位是epoch,低32位是zpoch内的自增id,由0开始。每次选出新的Leader,epoch会递增,同时zxid的低32位清0。

整个选主流程如下

  1. 状态变更。服务器启动的时候每个server的状态时Looking,如果是leader挂掉后进入选举,那么余下的非Observer的Server就会将自己的服务器状态变更为Looking,然后开始进入Leader的选举状态;

  2. 发起投票。每个server会产生一个(sid,zxid)的投票,系统初始化的时候zxid都是0,如果是运行期间,每个server的zxid可能都不同,这取决于最后一次更新的数据。将投票发送给集群中的所有机器;

  3. 接收并检查投票。server收到投票后,会先检查是否是本轮投票,是否来自looking状态的server;

  4. 处理投票。对自己的投票和接收到的投票进行PK:

先检查zxid,较大的优先为leader;如果zxid一样,sid较大的为leader;根据PK结果更新自己的投票,再次发送自己的投票

  1. 统计投票。每次投票后,服务器统计投票信息,如果有过半机器接收到相同的投票,那么leader产生,如果否,那么进行下一轮投票;

  2. 改变server状态。一旦确定了Leader,server会更新自己的状态为Following或者是Leading。选举结束。

我们要保证选主完成后,原来的主节点已经提交的事务继续完成提交;原主节点只是提出而没提交的事务要抛弃。这也是为什么倾向于选zxid最大的从节点为主节点,因为它上边的事务最新,最与原主节点保持一致。

总结

  1. Redis中的Sentinel选主相对来说更简单,因为不涉及事务状态的一致性

  2. Sentinel选主是基于raft协议,Zookeeper则基于Zab协议

  3. 二者都是收到半数的选票就选举成功

  4. Sentinel投票发消息主要内容是Sentinel id和配置纪元,Zookeeper则是 zxid和 sid

  5. Sentinel谁先来找他投票他就投谁,Zookeeper中则是要细细检查比较一番,检查内容包括epoch和节点状态,检查完毕后再跟自己的投票进行pk,进而看需不需要更新自己的投票,若是需要,则自己的投票也要广播出去

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值