zoukankan      html  css  js  c++  java
  • 第一章 Zookeeper理论基础

    1.1 什么Zookeeper?

      开源的分布式应用程序协调服务器,为分布式系统提供一致性服务。通过Paxos算法和ZAB协议完成,主要功能包括:配置维护、域名服务、分布式同步、集群管理

    1.2 一致性

    1.2.1 顺序一致性

      同一个客户端发起的多个事务请求,最终会严格按照其发起顺序记录到zk中

    1.2.2 原子性

      所有请求在ZK集群中的每个节点上是一致的,要么全部节点都是成功,要么全部都是失败

    1.2.3 单一视图

      客户端连接的集群中任意一节点,读取的数据都是一致的

    1.2.4 可靠性

      一旦事务被成功应用到zk,会一直保留下来,除非另一个事务将其修改

    1.2.5 最终一致性

      一旦一个事务被成功应用,zk可以保证在较短时间内,客户端最终一定能从服务端读取到最新的数据,但不保证实时读取到

    1.3 Paxos算法

      prepare阶段:提案者发送提案的编号为N给所有表决者,表决者用自己保存的最大接收编号maxN比较,只有N > maxN才同意,表决者缓存maxN = N,并发送自己历史最大接收提案 Proposal(myid,maxN,value)

      accept阶段:当半数表决者同意,提案者发送正真提案,Proposal(myid,N,value),表决者收到后,再次用maxN比较,只有N >= maxN,才同意,并更新Proposal(myid,N,value)。

      prepare和accept都必须要半数以上表决者同意,否则提案者只能重新进入prepare阶段

    1.3.1 活锁问题

      

      (图引用:https://blog.csdn.net/wolf_love666/article/details/92832811) 

      解决办法,只允许一个进程提交提案,即对N的增长有唯一操作权限

    1.4 ZAB协议  

      zookeeper 原子广播协议。当客户端连接到zk集群的一个节点后,如果客户端提交的读请求,节点直接响应。如果提交的是写请求,且当前节点不是Leader,会将请求转发给Leader,Leader以提案的方式广播该写操作,只有半数以上的节点同意写操作,写操作才会被提交,之后Leader会再次广播给所有订阅者,即Learner,通知它们同步数据。

    1.4.1 三类角色

    • Leader:事务请求的唯一处理者,也可以处理读请求
    • Follower:处理客户端读请求,将事务请求转发给Leader,对Leader的提案有表决权,同时可以参加Leader的选举,有选举权和被选举权
    • Observer:不参与选举,没有选举权和被选举权。可以协助Follower处理读请求,用来提高集群读请求吞吐量,同时不会增加选举压力

      再分类:

    • Learner:需要从Leader中同步数据的节点,Follower+Observer
    • QuorumServer:能参与选举的节点,Leader+Follower

    1.4.2 三个数据

    • zxid:Long型数字,高32位代表epoch,低32位表示xid
    • epoch:每个Leader选举结束会生成一个新的epoch,通知到集群中其他节点,包含Follower和Observer
    • xid:事务ID

    1.4.3 三种模式

    • 恢复模式:Leader崩溃或集群启动过程中,系统进入恢复模式,包含Leader选举和初始化同步
    • 广播模式:初始化广播和更新广播
    • 同步模式:初始化同步和更新同步。初始化广播触发Learner进行初始化同步,将初始化广播中的事务同步到本地。类似更新同步由更新广播触发,将正常通信阶段的事务同步到本地。

    1.4.4 四种状态

      集群中每个节点可能的状态

    • LOOKING:选举状态
    • FOLLOWING:Follower的正常工作状态
    • OBSERVING:Observer的正常工作状态
    • LEADING:Leader的正常工作状态

    1.4.5 同步模式和广播模式

      1. 初始化广播

      选举完毕后只是准Leader,需要经过初始化同步后,才能变成真正的Leader。这期间会将Leader本身有而其他Learner没有的事务广播出去,并且探测一下活跃的Learner。

    1. 为每个Learner创建一个FIFO队列
    2. 将新Leader中未同步的事务封装成Proposal
    3. 将Proposal逐条发送给各个Learner,并紧接着附加一个COMMIT消息
    4. Learner收到消息,更新到本地,成功后返回ACK
    5. Leader收到ACK后,将对应Learner加入可用的Follower或者Observer列表

      2. 消息广播算法

      当初始化完毕后,进入正常工作模式,当非Leader收到事务请求,将转发给Leader

    1. Leader封装事务为Proposal,并生成一个全局唯一的zxid
    2. 从Follower列表获取所有Follower,将Proposal通过各自的FIFO队列发送给对方
    3. Follower收到后,对比自身存储的最大zxid。大于最大zxid,存储到本地事务日志,返回Leader ACK
    4. 当Leader收到过半ACK,向所有Follower队列发送COMMIT消息,向所有Observer队列发送Proposal
    5. Follower收到后,会将日志中的事务正式更新到本地。Observer收到后,直接应用事务到本地。两者处理完后都需要发送ACK

      3. Observer的数量问题

      一般与Follower数量相同,Observer需要从Leader同步数据,但Observer同步时间小于等于Follower的同步时间,一旦Follower同步完成,那么Observer同步也将结束,这就导致可能部分尚未完成同步,那么这些未同步完成的Observer将不能对外提供服务,造成浪费

    1.4.6 恢复模式的三个原则

      1. Leader的主动让出原则

      当Leader收到Follower的心跳数量没有过半,此时Leader认为自己与集群的连接出现问题,会主动修改自己的状态为LOOKING,寻找新的Leader,防止出现脑裂。其他Server有过半主机发现Leader丢失,将会选举新的Leader

      2. 已经处理过的消息不能丢弃原则

      当Leader发送的COMMIT消息未完全被learner接收,Leader宕机,当新Leader选举后,需要根据这个来恢复执行

      3. 被丢弃的消息不能再现原则

      Leader在prepare阶段通过的事务,在发送COMMIT阶段之前宕机,再次上线后,需要丢弃这个事务

    1.4.7 Leader选举

      1. myid:也称为ServerId,是zk集群中服务器的唯一标识

      2. 逻辑时钟:Logicalclock,选举完毕,变成epoch

      一、集群启动中的Leader选举

      只有所有节点都处在LOOKING状态才能进行选举。每个服务器启动后,状态为LOOKING,会给自己投票(myid,zxid),将投票发送给集群所有服务器。投票的比较规则:

    • 优先检查zxid,较大的优先作为Leader
    • 若相同,比较myid,较大的作为Leader

      每个服务器会选出优胜票更新投票,直到有半数服务器收到相同的投票信息,优胜的更新状态为LEADING,失败的更新为FOLLOWING

      若后续再有服务器启动,发现其余节点不是LOOKIGN,自动更新状态为FOLLOWING

      二、宕机后的Leader选举

      首先更新状态为LOOKING,然后发送投票,每个服务器依然投给自己(myid,zxid),注意此时zxid可不是启动时的0。后续步骤一致

    1.5 高可用集群的容灾

    1.5.1 服务器数量的奇数和偶数

      无论写操作投票还是Leader选举的投票都需要半数以上节点同意,所以当半数以上节点宕机,则投票永远无法通过。如5台服务器只允许2台宕机,而6台也只允许2台宕机,所以5台和6台的容灾能力是一样的,基于容灾考虑,建议部署5台服务器避免浪费,但基于吞吐量,6台服务器更好

    1.5.2 容灾设计方案

      多机房部署设计,要充分考虑过半原则。比如三机房部署,每个机房中的主机数量要少于集群总数的一半,这样一个机房断网或断电,集群仍可以对外提供服务。双机房部署,需要个机房过半

    1.6 ZK和CAP

      zk遵循的是CP原则,牺牲了可用性。

      1. 当Leader宕机后,zk集群在选举时,不提供读写服务。

      2. 当过半下线后,集群也无法提供服务。

    1.7 ZK可能出现脑裂

      多机房部署,当出现网络连接,形成多个分区,可能出现脑裂,导致数据不一致。

      

    人生就像蒲公英,看似自由,其实身不由己。
  • 相关阅读:
    C#后台去除字符串最后一个字符
    C#后台验证含0的正整数
    jQuery提交表单的几种方式
    C#后台获取当前时间并格式化
    获取EasyUI日期输入框的值
    jQuery将字符串转换为数字
    JQ和JS获取span标签的内容
    正则
    json 拖拽
    event事件对象
  • 原文地址:https://www.cnblogs.com/walker993/p/14802358.html
Copyright © 2011-2022 走看看