zookeeper系列(五)—集群工作原理
转载:https://blog.csdn.net/w2cschool/article/details/105189365
前言
大家好,牧码心今天给大家推荐一篇zookeeper系列(五)—集群工作原理的文章,在实际工作中有很多应用场景,希望对你有所帮助。内容如下:
- 集群概要
- 集群部署
- 角色说明
- 工作原理
概要
ZooKeeper 是 Apache 的一个顶级项目,为分布式应用提供高效、高可用的分布式协调服务,提供了诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知和分布式锁等分布式基础服务,被广泛地应用于诸如 Hadoop、HBase、Kafka 和 Dubbo 等大型分布式系统中。其具体设计目标如下:
- 强一致性:客户端发起的事务请求,不能连接到集群的哪个节点,得到的结果是相同的。
- 可靠性:具有高可靠,可扩展的性能,要求数据能持久化,节点伸缩和扩展不影响对外提供的服务;
- 实时性:Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口;
- 原子性:更新只能成功或者失败,没有中间状态;
- 顺序性:所有节点能保证消息更新的顺序,如在一个节点上消息a在消息b前发布,则在所有节点上消息a都将在消息b前被发布;
下面我们来看下zookeeper官方提供的集群架构图:
图中每一个Server代表一个安装Zookeeper服务的节点。所有节点要求能相互感知,且在内存中维护当前的节点状态。客户端连接单个节点会发送TCP连接保持着通信,通过它发送请求、获取响应、获取监视事件和发送心跳等。如果到所连接节点的TCP连接中断,客户端将连接到集群中的另一个节点。
集群部署
要搭建一个高可用的zookeeper集群,首先要确定集群的规模,角色的分配。关于zookeeper集群规模确定,我们了解到zookeeper集群有“过半存活即可用”的特点,意思是一个 ZooKeeper 集群如果要对外提供可用的服务,那么集群中必须要有过半的机器正常工作并且彼此之间能够正常通信。基于这个特性,如果想搭建一个能够允许 N 台机器 down 掉的集群,那么就要部署一个由 2*N+1 台服务器构成的 ZooKeeper 集群。因此,一个由 3 台机器构成的 ZooKeeper 集群,能够在挂掉 1 台机器后依然正常工作,而对于一个由 5 台服务器构成的 ZooKeeper 集群,能够对 2 台机器挂掉的情况进行容灾。注意,如果是一个由6台服务器构成的 ZooKeeper 集群,同样只能够挂掉 2 台机器,因为如果挂掉 3 台,剩下的机器就无法实现过半了。因此我们一般会选择奇数台服务器(具体原因详见工作原理)搭建集群,那对比选择6台和选择5台区别在于选择6台在容灾能力上并没有任何显著的优势,反而多占用了一个服务器资源。
- 具体的集群部署参考集群部署
角色说明
上面我们分析了集群规模和集群部署,接下来我们分析集群中各角色,zookeeper 集群没有引入Master/Slave模式的角色概念,而是引入了Leader、Follower 和 Observer 三种角色。如下图所示,
上图各角色具体的说明如下:
角色 | 描述 |
---|---|
leader | 主节点,又名领导者。用于写入数据,通过选举产生,如果宕机将会选举新的主节点。 |
follower | 从节点,又名追随者。用于实现数据的读取。同时也是主节点的备选节点,并用拥有投票权。 |
observer | 观察者。用于读取数据,与fllower区别在于没有投票权,不能选为主节点。并且在计算集群可用状态时不会将observer计算入内。 |
- 关于observer配置:
只要在集群配置中加上observer后缀即可,示例如下:server.3=127.0.0.1:2889:3889:observer
- 1
工作原理
zookeer工作原理主要是Leader选举机制,数据同步流程,首先先介绍下会用到两个概念ZAB 协议&Paxos算法,有助于对工作原理的理解
- Paxos算法
Paxos 算法是莱斯利·兰伯特于1990年提出的一种基于消息传递且具有高度容错特性的一致性算法。在基于传递通信模型的分布式系统,不可避免的会发生以下错误:进程可能会慢、被杀死或者重启,消息可能会延迟、丢失、重复。Paxos算法可解决分布式系统中如何就某个值达成一致,保证不论发生以上任何异常,都不会破坏一致性。关于 Paxos算法具体介绍可参考 Paxos算法 - ZAB 协议
Zab协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议,是Zookeeper保证数据一致性的核心算法。Zab借鉴了Paxos算法,但又不像Paxos那样,是一种通用的分布式一致性算法,相比Paxos,Zab最大的特点是保证强一致性。Zab 协议包括两种基本的模式:崩溃恢复 和 消息广播,Zookeeper的核心是通过ZAB协议保证了各个Server之间的同步。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。关于ZAB协议具体介绍可参考ZAB协议 - ZXID (递增的事务id)
为了保证整个过程事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。Zxid 是一个 64 位的数字,其中低 32 位是一个简单的单调递增的计数器,针对客户端每一个事务请求,计数器加 1;而高 32 位则代表 Leader 周期 epoch 的编号,每个当选产生一个新的 Leader 服务器,就会从这个 Leader 服务器上取出其本地日志中最大事务的ZXID,并从中读取 epoch 值,然后加 1,以此作为新的 epoch,并将低 32 位从 0 开始计数。
epoch 编号可以理解为当前集群所处的年代,或者周期。每次Leader变更之后都会在 epoch 的基础上加1,这样旧的 Leader 崩溃恢复之后,其他Follower 也不会听它的了,因为 Follower 只服从epoch最高的 Leader 命令。
选举机制
假设有一个zookeeper集群包含server1,server2,server3等3个节点,每个节点在工作过程会包含3中状态:LOOKING,LEADING,FOLLOWING 。而集群的Leader选举会以下两种情况时触发:
- 服务节点初始化启动。当节点初始起动时会在集群中寻找Leader节点,如果找到则与Leader建立连接,其自身状态变化follower或observer。如果没有找到Leader,当前节点状态将变化LOOKING,进入选举流程;
- 半数以上的节点无法和Leader建立连接。在集群运行其间如果有follower或observer节点宕机只要不超过半数并不会影响整个集群服务的正常运行。但如果leader宕机,将暂停对外服务,所有follower将进入LOOKING 状态,进入选举流程。
zookeeper的选举过程包含发起投票—>接收投票—> 处理投票—>统计投票—> 更新状态,这里以basic paxos算法的选举流程说明,如图所示:
根据流程图,整个过程说明如下:
- 发起投票:初始情况下,server1,server2,server3都会进行投票(包括给自己),每次投票会包含所推举的节点的myid和ZXID,使用(myid, ZXID)来表示,此时Server1的投票为(1, 0),Server2的投票为(2, 0),Server2的投票为(3, 0),然后各自将这个投票发给集群中其他机器。而Leader宕机情况下,如Server2宕机,余下的非Observer节点会将自己的状态变更为LOOKING,然后开始进入Leader选举流程;
- 接受来自每个节点的询问:集群的每个节点接受到其他节点询问后,首先验证投票的有效性,是否由自身发起,是否是本轮投票;
- 处理投票:收到所有节点回复,就计算出zxid最大的哪个节点,并将这个节点相关信息设置成下一次要投票的节点。;
- 统计投票:计算这过程中获得票数最多的的节点为获胜者,如果获胜者的票数超过半数,则该节点被选为leader。否则,继续这个过程,直到leader被选举出来;
- 更新状态:确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING,进入下一轮投票。
数据同步
完成Leader选举后,为了保证各节点数据的一致性,zookeeper会进行数据和状态同步,数据同步时也会涉及到两个流程:
1.客户端在正常情况下提交数据;
2.集群中某个节点宕机恢复后的数据同步;
- 客户端写入数据流程,流程如图所示:
根据流程图说明下具体的过程:
- 客户端向zk中的server发送写请求,如果该server不是leader,则会将该写请求转发给leader server,leader将请求事务以proposal(提议)形式分发给follower;
- 当follower收到收到leader的proposal时,根据接收的先后顺序处理proposal;
- 当Leader收到follower针对某个proposal过半的ack后,则发起事务提交,重新发起一个commit的proposal
- Follower收到commit的proposal后,记录事务提交,并把数据更新到内存数据库;
- Follower更新成功后,反馈给client。
- 宕机节点恢复后的数据同步
在集群运行过程当中如果有一个follower节点宕机,由于宕机节点没过半,集群仍然能正常服务。当leader 收到新的客户端请求,此时无法同步给宕机的节点。造成数据不一至。为了解决这个问题,当节点启动时,首先找当前工作的Leader,比对数据是否一致(通过比对ZXID来确认)。不一致则开始同步(同步流程与客户端写入流程一致),同步完成之后在进行对外提供服务。
工作流程
-
leader节点工作流程
1.恢复数据;
2.维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型; -
follower节点工作流程
1.向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
2.接收Leader消息并进行处理;
3 .接收Client的请求,如果为写请求,发送给Leader进行投票;
4 .返回Client结果。
Follower的消息处理如下几种来自Leader的消息:
1.PING消息:心跳消息;
2.PROPOSAL消息:Leader发起的提案,要求Follower投票;
3.COMMIT消息:服务器端最新一次提案的信息;
4.UPTODATE消息:表明同步完成;
5.REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
6.SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。