美文网首页
分布式基础-选谁当老大(二)

分布式基础-选谁当老大(二)

作者: 明翼 | 来源:发表于2020-09-25 23:26 被阅读0次

    前言

    上次讨论到谁当老大的问题,介绍了Bully选主算法,比较简单,直接选ID最大或最小的作为leader。这样粗暴的选举算法,没有考虑到数据的新旧,所以可能更容易造成数据丢失的问题。

    单纯的论资排辈不一定是最合适的,老人可能没新人能力强,所以又发明了其他的分布式选举算法。本次介绍的是ZAB算法,就是更民主的,选举更新的数据的节点作为leader。ZAB算法全称:Zookeeper Atomic Broadcast ,用一句话解释ZAB协议是保障操作顺序性的,基于主备模式的原子广播协议。

    Zookeeper 作为分布式应用服务器,由于高性能和稳定性,和可靠性得到了广泛的应用。
    它由Leader,Follower和Observer三种身份成员组成。

    • Leader : 作为主节点,负责处理写请求,客户端发送的写请求只能由Leader来处理,如果发送给了Follower,则需要转发给Leader,Leader广播方式再把数据同步给Follower。
    • Follower: 作为备份节点,负责数据的读请求,所以读的能力不够话,可以通过增加Follower个数来提升整体的读能力。
    • Observer: 观察者节点,不参与投票,具备读写能力,大规模集群情况下,比如solr集群,极度依赖Zookeeper,如果通过增加Follower 来提升读的能力的话,当时由于节点增加了,所以会造成选举比较忙,影响写操作性能,所以这时候增加观察者节点比较好。
    # 可以查看zkserver的服务器的身份
    ./zkServer.sh status
    
    Zookeeper类似文件系统存储结构

    一 如何选举

    ZAB 支持三种成员身份,有四种状态,三种状态分别代表三种身份。

    • FOLLOWING: 跟随者状态,表示此节点是Follower。
    • LEADING: 领导者状态,表示此节点为Leader。
    • OBSERVING: 观察者状态,表示此节点是观察者。
      除了三种状态,集群刚开始启动的时候或者领导者挂了之后,需要重新选举,标记选举的的状态是LOOKING状态。

    选举采用投票形式,被选为Leader的不同节点进行相互PK,获取大多数节点投票的Leader会当选。
    投票的信息为<Leader, Epoch, LastZxid,node>

    Leader :表示为投选择哪个节点作为leader;Epoch:第多少届选举(有的叫任期,我觉得多少届更好),递增的,有这个是为了防止消息延迟造成的不同伦消息相互干扰;LastZxid: 表示被选举为Leader的节点的最大事务ID;Node:即投票的节点。

    举例说明: < 3, 1,101,B>
    这里面表示节点B 提议节点ID:3 在第一届选举中作为Leader,节点ID:3的最大事务ID为101。
    节点开始都会投给自己,然后将此投票信息发送给其他节点,节点收到投票信息后,会进行以下PK:

    选举过程

    PK过程很简单,届大的获胜,比如人家已经在进行第二轮选举了,你进行第一轮选举,老的失效;
    如果时同届选举,lastzxid大的获胜,大的说明数据更新;如果数据一样新,那么大的serverid获胜。
    当一个节点获得大部分节点的票之后,就可以当选为leader了。

    节点ID可以通过在zoo.cfg里面看到或配置的data目录下有个myid文件,里面也是此节点的id。


    集群节点配置

    我们以最常见的三个节点组成的Zookeeper集群,来阐述zk如何进行选举。


    Zookeeper集群

    说明: 初始时候节点A是Leader,节点B和节点C是Follower,只所以选用三个节点,是因为ZK在处理选举或同步数据时候,需要大多数确认,所以一般都是奇数个节点,只所以节点用三个,因为一个不可靠;五个这种选举慢,写性能会弱些,一般三个就够了。

    1.1 发生故障 进入选举状态

    这时候,节点A发生故障,或网络出现问题,节点B和节点C读取消息的时候超时,进入到LOOKING状态,发起领导者选举,如下:


    LOOKING状态

    1.2 投票

    进入选举阶段后,每个节点都会生成投票信息,初始的时候每个节点都投自己一票,假设节点B的最大事务id为100,serverid为2;节点C的最大事务id为101,serverid为3,则投票的信息如下:


    投票

    投票消息不光发给其他节点,也发给自己节点。如上图,节点B收到节点C发来的投票信息[3,1,101,C]之后,进行pk,发现届都是1,但是C的最大事务ID:101 大于B的最大的事务ID:100,所以C获胜。B节点调整自己的投票信息:[3,1,101,B] 将这个消息发送给自己和C节点。节点C收到消息后进行PK,C获胜所以不用调整投票信息。

    1.3 得到投票结果

    按照刚才的逻辑,每个节点都有累加的投票信息,节点ID为3即节点C获得了大多数投票。


    投票结果

    这样节点C就变更状态为LEADING状态,节点B就变更为FOLLOWING状态。zookeeper就是通过这种方式完成了尽量选择数据最新的节点作为Leader节点。


    选举成功

    二 ZAB算法特点

    ZAB算法的性能不错,对系统没有什么特殊的要求。

    • 消息风暴: 但是从通过上面的描述可以看出每次选票都要广播给每个节点,如果集群中有n个节点,则需要发送的消息量为n*(n-1)个消息,容易出现消息风暴。
    • 算法稳定性好: 当新节点加入集群或发生故障之后,会触发重新选举,但是不一定会切主,除非新选举的节点的最新的事务id大于现在leader的事务id和节点ID最大,且获得半数以上投票才会进行切主。

    三 ZAB选举之后

    ZAB选举完成之后,并不能立刻处理请求,还要经历集群发现阶段和数据同步阶段后才可以提供读写服务。
    简单的聊下。

    • DISCOVERY 集群发现阶段
      领导者在选举完成后,需要递增自己的选举届号(任期编号),然后通过和跟随者协商来完成领导者的确认。

    比如刚才的B节点和C节点需要进入到DISCOVERY状态,具体如下图:


    集群发现阶段
    1. Follwer 主动向Leader发送FollwINFO消息,标注上一届的编号为1.
    2. Leader 回复Follwer LEADINFO消息,包含本次新生成的选举届号2,和本届的事务id为0.
    3. Follwer 判断下如果收到Leader的选举届号更大,则是合法的Leader,回复确认消息ACKEPOH。
    4. Leader收到绝大多数的节点返回的ACKEPOH的确认后就可以正式当选Leader,开展领导者的工作了。
      这时ZAB的状态变更为数据同步状态SYNCHRONIZATION。
    • SYNCHRONIZATION数据同步阶段
      刚才的集群发现阶段完成了领导者的确认,数据同步阶段完成的是数据的恢复和同步。
      同步数据的过程如下:


      数据同步
    1. Leader 通过比较和Follower数据差异大小选择同步方式,将差异数据放入到队列中。
    2. Leader生成New Leader消息也发送到队列中。
    3. Leader将队列中的数据发送给Follower。
    4. Follower 完成数据的同步。
    5. Follower 回复ACK消息给Leader。
    6. 当Leader 收到大部分节点的ACK消息后,发送UPDATE消息给Follower,表示节点同步完成,进入到广播阶段BROADCAST,正式开始处理消息了。

    刚才说数据同步的方式有几种,不同情况选择不同的方式。Leader在内存队列中保存了最近500个(默认)事务ID的最大值和最小值。

    • TRUNC:当Follower的最新的事务ID比Leader事务最大ID,还大发送消息给Follower根据Leader的最大事务ID丢弃已经提交的事务;
    • DIFF:当Follower的最新事务在Leader的两个事务ID之间,采用DIFF方式来完成数据同步,领导者将Follower没有的事务同步给Follower。
    • SNAP:当Follower的最新事务小于Leader的最小事务的时候,采用SNAP的方式,同步Leader的本地快照给Follower,Follower直接覆盖本地内容。

    其他说明下:

    1. zookeeper是实现的最终一致性,写入到zookeeper的消息,如果通过客户端向任意的节点发起读请求,不一定会读到最新的数据,如果需要读到最新的数据,可以先执行sync命令后再读取节点数据。

    2. zookeeper 对于复制到大多数节点的事务不会丢失,但是对于只复制到少数节点的事务,有可能最终被保留,也有可能被截断,要看新选举的Leader是否包含这个事务。

    四诗词欣赏

    古诗十九首
    
    [汉] [汉无名氏] 
    
    回车驾言迈,
    
    悠悠涉长道。
    
    四顾何茫茫,
    
    东风摇百草。
    
    所遇无故物,
    
    焉得不速老。
    
    盛衰各有时,
    
    立身苦不早。
    
    人生非金石,
    
    岂能长寿考?
    
    奄忽随物化,
    
    荣名以为宝。
    
    
    

    相关文章

      网友评论

          本文标题:分布式基础-选谁当老大(二)

          本文链接:https://www.haomeiwen.com/subject/ogutuktx.html