官方文档上这么解释zookeeper,它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
zk的一致性提现在一下几方面:
Paxos算法是Zookeeper实现的基础,有一篇文章标题更是以“Zookeeper全解析——Paxos作为灵魂” 作为标题,里面解析的更透彻
Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX中的"La",此人现在在微软研究院)于1990年提出的一种基于消息传递的一致性算法。这个算法被认为是类似算法中最有效的。
Paxos算法解决的问题是一个分布式系统如何就某个值(决议)达成一致。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点执行相同的操作序列,那么他们最后能得到一个一致的状态。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。一个通用的一致性算法可以应用在许多场景中,是分布式计算中的重要问题。因此从20世纪80年代起对于一致性算法的研究就没有停止过。节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。Paxos 算法就是一种基于消息传递模型的一致性算法
占庭将军问题含义是在存在消息丢失的不可靠信道上试图通过消息传递的方式达到一致性是不可能的。因此Paxos算法的前提下是 拜占庭将军问题不存在
4.4.1 三种角色
在Paxos算法中有三种角色,分别对应着三种不同的行为,但在很多时候,一个进程可能同时充当着多种角色
4.4.2 Paxos 算法的一致性
Paxos算法的一致性主要体现在以下几点:
没有提案被提出则不会有提案被选定
每一个提议者在提出提案是首先都会获取一个具有唯一性且递增的提案编号N。然后该编号会被赋予其要提出的提案。
每一个表决者在通过(Accept)提案之后 ,会将该提案的编号N 记录在本地。这样每一个表决者中保存的已经被通过(Accept)的提案中会存在一个编号最大的提案,假设其为maxN。每一个表决者只会通过比自己本地maxN大的提案。
在众多提案中有且仅有一个提案被选定。
一旦一个提案被选定,其他服务器会主动同步(Learn)改提案到本地
4.4.3 算法过程描述
paxos算法的执行分为两个阶段:准备阶段( prepare) 和 接受阶段(accept)
A. prepare阶段
提议者准备提交一个编号为N的提议,首先向表决者发送一个proposal(N)的请求,用于试探集群是否支持该编号的提案。
每一个表决者会保存自己曾通过的提案中最大的编号maxN,当表决者收到提案者发送过来的请求时,会比较 proposal(N) 和自己保存的maxN,会有以下几种情况
maxN>N:表明提案已过时,表决者不回应或者回应Error来表示拒绝该提案。
maxN 若当前表决者还未通过任何提案,则会返回proposal(myid,null,null)
B. accept 阶段
4.5 paxos活锁问题
有很多算法对paxos算法进行了改进,比如 fast paxos ,EPaxos,Multi Paxos等
例如 paxos算法中存在 “活锁问题” ,Fast Paxos 算法进行了改进:只允许一个进程处理写请求(其具有对N的唯一操作权),解决了活锁问题
ZAB ,Zookeeper Atomic Broadcast,zk 原子消息广播协议,是专为 ZooKeeper 设计的一 种支持崩溃恢复的原子广播协议,在 Zookeeper 中,主要依赖 ZAB 协议来实现分布式数据 一致性。 Zookeeper 使用一个单一主进程来接收并处理客户端的所有事务请求,即写请求。当服 务器数据的状态发生变更后,集群采用 ZAB 原子广播协议,以事务提案 Proposal 的形式广 播到所有的副本进程上。ZAB 协议能够保证一个全局的变更序列,即可以为每一个事务分配 一个全局的递增编号 xid。 当 Zookeeper 客户端连接到 Zookeeper 集群的一个节点后,若客户端提交的是读请求, 那么当前节点就直接根据自己保存的数据对其进行响应;如果是写请求且当前节点不是 Leader,那么节点就会将该写请求转发给 Leader,Leader 会以提案的方式广播该写操作,只 要有超过半数节点同意该写操作,则该写操作请求就会被提交。然后 Leader 会再次广播给 所有订阅者,即 Learner,通知它们同步数据。
ZAB 协议是 Fast Paxos 算法的一种工业实现算法。但两者的设计目标不太一样。ZAB 协 议主要用于构建一个高可用的分布式数据主备系统,例如,Leader 挂了,马上就可以选举出 一个新的 Leader。而 Paxos 算法则是用于构建一个分布式一致性状态机系统,确保系统中各 个节点的状态都是一致的。 另外,ZAB 还使用 Google 的 Chubby 算法作为分布式锁的实现,而 Google 的 Chubby 也 是 Paxos 算法的应用。
为了避免 Zookeeper 的单点问题,zk 也是以集群的形式出现的。zk 集群中的角色主要有 以下三类:
这三类角色在不同的情况下又有一些不同的叫法。
在 ZAB 中有三个很重要的数据:
ZAB 协议中对 zkServer 的状态描述有三种模式。这三种模式并没有十分明显的界线,它 们相互交织在一起。
1. 初始化同步
前面我们说过,恢复模式具有两个阶段:Leader 选举与初始化同步。当完成 Leader 选 举后,此时的 Leader 还是一个准 Leader,其要经过初始化同步后才能变为真正的 Leader。
具体过程如下:
2. 消息广播算法
当集群中已经有过半的 Follower 完成了初始化状态同步,那么整个 zk 集群就进入到了 正常工作模式了。
如果集群中的其他节点收到客户端的事务请求,那么这些 Learner 会将请求转发给 Leader 服务器。然后再执行如下的具体过程:
1. 已被处理过的消息不能丢
当 Leader 收到超过半数 Follower 的 ACKs 后,就向各个 Follower 广播 COMMIT 消息, 批准各个 Server 执行该写操作事务。当各个 Server 在接收到 Leader 的 COMMIT 消息后就会 在本地执行该写操作,然后会向客户端响应写操作成功。 但是如果在非全部 Follower 收到 COMMIT 消息之前 Leader 就挂了,这将导致一种后 果:部分 Server 已经执行了该事务,而部分 Server 尚未收到 COMMIT 消息,所以其并没有 执行该事务。当新的 Leader 被选举出,集群经过恢复模式后需要保证所有 Server 上都执行 了那些已经被部分 Server 执行过的事务。
2. 被丢弃的消息不能再现
当 Leader 接收到事务请求并生成了 Proposal,但还未向任何 Follower 发送时就挂了, 因此,其他 Follower 根本就不知道该 Proposal 的存在。当新的 Leader 选举出来,整个集群 进入正常服务状态后,之前挂了的 Leader 主机重新启动并注册成为了 Follower。若那个别 人根本不知道的 Proposal 还保留在那个主机,那么其数据就会比其它主机多出了内容,导致 整个系统状态的不一致。所以,该 Proposa 应该被丢弃。类似这样应该被丢弃的事务,是不 能再次出现在集群中的,应该被清除。
当集群正在启动过程中,或 Leader 与超过半数的主机断连后,集群就进入了恢复模式。 而恢复模式中最重要的阶段就是 Leader 选举。
1. Leader 选举中的基本概念
myid
这是 zk 集群中服务器的唯一标识,称为 myid。例如,有三个 zk 服务器,那么编号分别 是 1,2,3。
逻辑时钟
逻辑时钟,Logicalclock,是一个整型数,该概念在选举时称为 logicalclock,而在选举结 束后称为 epoch。即 epoch 与 logicalclock 是同一个值,在不同情况下的不同名称。
zk 状态
zk 集群中的每一台主机,在不同的阶段会处于不同的状态。每一台主机具有四种状态。
2. Leader 选举算法
在集群启动过程中的 Leader 选举过程(算法)与 Leader 断连后的 Leader 选举过程稍微 有一些区别,基本相同。
集群启动中的 Leader 选举
若进行 Leader 选举,则至少需要两台主机,这里以三台主机组成的集群为例。
在集群初始化阶段,当第一台服务器 Server1 启动时,其会给自己投票,然后发布自己 的投票结果。投票包含所推举的服务器的 myid 和 ZXID,使用(myid, ZXID)来表示,此时 Server1 的投票为(1, 0)。由于其它机器还没有启动所以它收不到反馈信息,Server1 的状态一直属于 Looking,即属于非服务状态。
1582658285742.png
当第二台服务器 Server2 启动时,此时两台机器可以相互通信,每台机器都试图找到 Leader,选举过程如下:
每个 Server 发出一个投票。此时 Server1 的投票为(1, 0),Server2 的投票为(2, 0),然后 各自将这个投票发给集群中其他机器。
接受来自各个服务器的投票。集群的每个服务器收到投票后,首先判断该投票的有效 性,如检查是否是本轮投票、是否来自 LOOKING 状态的服务器。
处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行 PK,PK 规则如下:
对于 Server1 而言,它的投票是(1, 0),接收 Server2 的投票为(2, 0)。其首先会比较两者 的 ZXID,均为 0,再比较 myid,此时 Server2 的 myid 最大,于是 Server1 更新自己的投票为 (2, 0),然后重新投票。对于 Server2 而言,其无须更新自己的投票,只是再次向集群中所有 主机发出上一次投票信息即可。
统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到 相同的投票信息。对于 Server1、Server2 而言,都统计出集群中已经有两台主机接受了(2, 0) 的投票信息,此时便认为已经选出了新的 Leader,即 Server2
改变服务器状态。一旦确定了 Leader,每个服务器就会更新自己的状态,如果是 Follower,那么就变更为 FOLLOWING,如果是 Leader,就变更为 LEADING。
添加主机。在新的 Leader 选举出来后 Server3 启动,其想发出新一轮的选举。但由于 当前集群中各个主机的状态并不是 LOOKING,而是各司其职的正常服务,所以其只能是以 Follower 的身份加入到集群中。
断连后的 Leader 选举
在 Zookeeper 运行期间,Leader 与非 Leader 服务器各司其职,即便当有非 Leader 服务 器宕机或新加入时也不会影响 Leader。但是若 Leader 服务器挂了,那么整个集群将暂停对 外服务,进入新一轮的 Leader 选举,其过程和启动时期的 Leader 选举过程基本一致。
sss
CAP 原则又称 CAP 定理,指的是在一个分布式系统中,Consistency(一致性)、Availability (可用性)、Partition tolerance(分区容错性),三者不可兼得。
对于分布式系统,网络环境相对是不可控的,出现网络分区是不可避免的,因此系统必 须具备分区容错性。但其并不能同时保证一致性与可用性。CAP 原则对于一个分布式系统来 说,只可能满足两项,即要么 CP,要么 AP。这就是 CAP 的三二原则。
BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent(最 终一致性)三个短语的简写
BASE 理论的核心思想是:即使无法做到强一致性,但每个系统都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。
基本可用
基本可用是指分布式系统在出现不可预知故障的时候,允许损失部分可用性。
软状态
软状态,是指允许系统数据存在的中间状态,并认为该中间状态的存在不会影响系统的 整体可用性,即允许系统主机间进行数据同步的过程存在一定延时。软状态,其实就是一种 灰度状态,过渡状态。
最终一致性
最终一致性强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能够达到 一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需 要实时保证系统数据的强一致性。
在没有发生故障的前提下,数据达到一致状态的时间延迟,取决于网络延迟,系统负载 和数据复制方案设计等因素。
zk 遵循的是 CP 原则,即保证了一致性,但牺牲了可用性。体现在哪里呢?
当 Leader 宕机后,zk 集群会马上进行新的 Leader 的选举。但选举时长在 30-200 毫秒间, 整个选举期间 zk 集群是不接受客户端的读写操作的,即 zk 集群是处于瘫痪状态的。所以, 其不满足可用性