zoukankan      html  css  js  c++  java
  • ZAB协议(转)

    转自https://www.cnblogs.com/frankltf/p/10392151.html

    ZAB协议

    ZAB协议是专门为zookeeper实现分布式协调功能而设计,zookeeper主要是根据ZAB协议是实现分布式系统数据一致性

    zookeeper根据ZAB协议建立了主备模型完成zookeeper集群中数据的同步

    这里所说的主备系统架构模型是指

    在zookeeper集群中,只有一台leader负责处理外部客户端的事物请求(或写操作),然后leader服务器将客户端的写操作数据同步到所有的follower节点中

    enter image description here

    ZAB的协议核心是在整个zookeeper集群中只有一个节点即Leader将客户端的写操作转化为事物(或提议proposal)

    • leader节点在数据写完之后,将向所有的follower节点发送数据广播请求(或数据复制),等待所有的follower节点反馈
    • 在ZAB协议中,只要超过半数follower节点反馈OK,即leader收到半数以上ACK,就会发送commit指令给FIFO队列
    • FIFO队列把commit给Follower,即Leader向所有的follower服务器发送commit消息,实现数据同步

    enter image description here

    ZAB协议中主要有两种模式,第一是消息广播模式;第二是崩溃恢复模式

    消息广播模式

    • 在zookeeper集群中数据副本的传递策略就是采用消息广播模式
    • zookeeper中数据副本的同步方式与二阶段提交相似但是却又不同
    • 二阶段提交的要求协调者必须等到所有的参与者全部反馈ACK确认消息后,再发送commit消息
    • 要求所有的参与者要么全部成功要么全部失败
    • 二阶段提交会产生严重阻塞问题
    • ZAB协议中Leader等待follower的ACK反馈是指”只要半数以上的follower成功反馈即可,不需要收到全部follower反馈”

    enter image description here

    zookeeper中消息广播的具体步骤如下:

    客户端发起一个写操作请求

    • leader服务器将客户端的request请求转化为事物proposql提案,同时为每个proposal分配一个全局唯一的ID,即ZXID
    • leader服务器与每个follower之间都有一个队列,leader将消息发送到该队列
    • follower机器从队列中取出消息处理完(写入本地事物日志中)毕后,向leader服务器发送ACK确认
    • leader服务器收到半数以上的follower的ACK后,即认为可以发送commit
    • leader向所有的follower服务器发送commit消息
    • zookeeper采用ZAB协议的核心就是只要有一台服务器提交了proposal,就要确保所有的服务器最终都能正确提交proposal,这也是CAP/BASE最终实现一致性的一个体现
    • leader服务器与每个follower之间都有一个单独的队列进行收发消息,使用队列消息可以做到异步解耦
    • leader和follower之间只要往队列中发送了消息即可,如果使用同步方式容易引起阻塞,性能上要下降很多

    崩溃恢复

    zookeeper集群中为保证任何所有进程能够有序的顺序执行,只能是leader服务器接受写请求,即使是follower服务器接受到客户端的请求,也会转发到leader服务器进行处理

    如果leader服务器发生崩溃,则zab协议要求zookeeper集群进行崩溃恢复和leader服务器选举

    ZAB协议崩溃恢复要求满足如下2个要求

    • 确保已经被leader提交的proposal必须最终被所有的follower服务器提交
    • 确保丢弃已经被leader发出但是没有被提交的proposal

    根据上述要求,新选举出来的leader不能包含未提交的proposal,即新选举的leader必须都是已经提交了的proposal的follower服务器节点

    同时,新选举的leader节点中含有最高的ZXID

    这样做的好处就是可以避免了leader服务器检查proposal的提交和丢弃工作

    leader服务器发生崩溃时分为如下场景

    • leader在提出proposal时未提交之前崩溃,则经过崩溃恢复之后,新选举的leader一定不能是刚才的leader
    • 因为这个leader存在未提交的proposal
    • leader在发送commit消息之后,崩溃。即消息已经发送到队列中
    • 经过崩溃恢复之后,参与选举的follower服务器(刚才崩溃的leader有可能已经恢复运行,也属于follower节点范畴)中有的节点已经是消费了队列中所有的commit消息
    • 即该follower节点将会被选举为最新的leader。剩下动作就是数据同步过程

    数据同步

    • 在zookeeper集群中新的leader选举成功之后,leader会将自身的提交的最大proposal的事物ZXID发送给其他的follower节点
    • follower节点会根据leader的消息进行回退或者是数据同步操作
    • 最终目的要保证集群中所有节点的数据副本保持一致

    数据同步完之后,zookeeper集群如何保证新选举的leader分配的ZXID是全局唯一呢?这个就要从ZXID的设计谈起

    • ZXID是一个长度64位的数字,其中低32位是按照数字递增,即每次客户端发起一个proposal,低32位的数字简单加1
    • 高32位是leader周期的epoch编号
    • 每当选举出一个新的leader时,新的leader就从本地事物日志中取出ZXID,然后解析出高32位的epoch编号,进行加1
    • 再将低32位的全部设置为0,这样就保证了每次新选举的leader后,保证了ZXID的唯一性而且是保证递增的

    enter image description here

    ZAB协议原理

    • ZAB协议要求每个leader都要经历三个阶段,即发现,同步,广播

    发现

    • 要求zookeeper集群必须选择出一个leader进程,同时leader会维护一个follower可用列表,将来客户端可以这follower中的节点进行通信

    同步

    • leader要负责将本身的数据与follower完成同步,做到多副本存储
    • 体现了CAP中高可用和分区容错,follower将队列中未处理完的请求消费完成后,写入本地事物日志中

    广播

    • leader可以接受客户端新的proposal请求,将新的proposal请求广播给所有的follower

    Zab与Paxos

    Paxos算法的确是不关心请求之间的逻辑顺序,而只考虑数据之间的全序,但很少有人直接使用paxos算法,都会经过一定的简化、优化

    Paxos算法在出现竞争的情况下,其收敛速度很慢,甚至可能出现活锁的情况

    例如当有三个及三个以上的proposer在发送prepare请求后,很难有一个proposer收到半数以上的回复而不断地执行第一阶段的协议

    为了避免竞争,加快收敛的速度,在算法中引入了一个Leader这个角色,在正常情况下同时应该最多只能有一个参与者扮演Leader角色,而其它的参与者则扮演Acceptor的角色

    在这种优化算法中,只有Leader可以提出议案,从而避免了竞争使得算法能够快速地收敛而趋于一致

    而为了保证Leader的健壮性,又引入了Leader选举,再考虑到同步的阶段,渐渐的你会发现对Paxos算法的简化和优化已经和上面介绍的ZAB协议很相似了

    FastLeaderElection

    enter image description here

    论读书
    睁开眼,书在面前
    闭上眼,书在心里
  • 相关阅读:
    Codeforces Round #404 (Div. 2) C. Anton and Fairy Tale
    Codeforces Round #402 (Div. 2) D.String Game
    30.algorithm排序小结
    28.数值算法小结
    28.STL常用算法
    27.改变数据的数值算法
    26.不改变数据的数值算法
    25.不改变原生数据的STL algorithm
    24.迭代器(流迭代器,正向,反向迭代器,分配器,存储迭代器)
    22.允许重复的容器(unordered_multiset)
  • 原文地址:https://www.cnblogs.com/YC-L/p/14470604.html
Copyright © 2011-2022 走看看