本文首发自「慕课网」,想了解更多IT干货,程序员圈热闻,欢迎关注“慕课网”或慕课网微信官方账号!
作者:大能 | 慕课网讲师
本文将从如何保证Zookeper集群的一致性,谈谈zookeper保证数据一致性的协议,然后展开Zookeper集群Leader选举,包括集群三个节点的类型,ZAB协议中节点的四种状态,以及两种情况下Leader选举的过程。然后将详细介绍ZAB协议,包括ZXID在ZAB协议中的结构、ZAB协议的两个重点、崩溃恢复模式和新闻广播模式。然后通过一个例子来解释ZAB协议中Leader的单点问题,然后导致Paxos算法。本文将分为上下两章,本文为第一部分。
Zookeper集群确保数据一致性首先,让我们了解一致性。
一致性我们使用集群来提高整个系统的可用性,即使挂了几个节点,整个集群仍然可以提供服务。好吧,在zookeeper集群的每个节点上,它存储的数据都是全数据,也就是说,它们之间存储的每个节点都是相同的数据,正如我们前面提到的,集群中的每个节点都可以提供读取服务,所以在这种情况下,我们必须确保多个节点之间的数据是一致的,这样就不会连接不同的节点来读取不同的值,对吧?也就是说,我们需要确保集群节点之间数据的一致性。然后我们来看看zookeper集群是如何做到这一点的,也就是如何同步节点间的数据
zookeeper保证数据一致性的协议ZAB协议用于确保我们的zookeper中的数据一致性。通过此协议,Zookeeper集群之间的数据同步,以确保数据的一致性。
先简单看一下zab协议的工作流程(图):
Zookeper编写数据的机制是客户端将编写请求发送到leader节点。如果发送follower节点,follower节点将将编写请求转发到leader节点。leader节点将通过proposal请求将数据发送到所有节点,包括您自己。在接收到数据后,所有节点都将写入本地磁盘,写完之后会给leader发一个ack请求。只要leader接收到一半以上的节点并发送ack响应,它就会向每个节点发送commit消息,每个节点都会将消息放入内存中。内存是为了保证高性能,用户会看到消息。
此时,如果Zookeeper想要保证数据的一致性,则需要考虑以下两种情况
- 情况一:leader执行commit。在给follower发commit之前,leader已经关闭。此时如何保证消息的一致性?
- 情况二:leader的事务性请求已在一些节点中应用,此时leader已挂断,如何保证消息的一致性?
如果Leader出现故障,未提交事务请求,即只在Leader服务器上提出但未提交的操作需要丢弃。因为事实上,它只是完成了第一阶段。
Leader故障和事务请求已提交,即Leader服务器上提交的操作最终由所有服务器节点提交。当谈到ZAB协议时,这个概念更加清晰。如果在某个节点成功提交应用程序,则该节点的zxid必须更大,并决定它将被选为一个新的leader。然后同步。
Zookeper集群Leader选举Zookeper集群中的三种节点当节点在运行过程中出现故障时,该集群是如何应对的?
Zookeeper中有三种类型的节点,对吧?让我们逐一看看:
- Observer节点只是为了提高阅读性能,不会参与任何决策过程。因此,即使挂断,也不会影响集群的正常运行。
- Folllower节点,如果少数节点挂断,即使不超过一半,也不会受到影响。如果故障节点超过一半,此时就没有办法了。节点恢复后才能运行
- Leader节点,通过之前的学习,我们也知道这个Leader在整个集群中起着至关重要的作用,整个集群的协调工作都是由它发起的。因此,如果Leader在这个时候挂断,整个集群就无法正常运行,这不是一半以上的问题。
因此,当Leader节点挂断时,有必要尽快从可用的节点中选择一个节点作为新的Leader,以恢复集群的可用性。如何在这里选择新的Leader是一个需要解决的问题。让我们考虑一下。你能简单地从剩下的follower节点中选择一个新的领导者吗?我们可以考虑这个场景:Leader故障,事务请求已提交
,在这个场景中,我们的follower节点的状态明显不同,所以我们当时也说过,在这个场景中,Zookeper集群有机制确保这个server1成为新的领导者。这里涉及到Zookeper集群的Leader选举算法。这个算法对于保证Zookeeper集群的可用性和数据一致性非常重要,所以我们来详细看看这个算法是什么样的处理过程。
在开始分析算法之前,让我们来看看集群中节点的几种状态,因为整个选举过程都涉及到这些状态的流通。
ZAB 节点中有四种状态- looking:节点处于选举状态
- following:当前节点是跟随者,服从 leader 该节点的命令将参与投票
- Obsering:观察状态,同步leader状态,但不参与投票
- leading:当前节点是 leader,协调事务
好了,我们来看看Leader的选举过程,所以对于Zookeeper集群来说,当出现以下两种情况时,需要Leader选举:
- 在集群启动期间,Leader选举
- 集群运行期间,Leader故障
然后整个Leader选举过程就是一个投票过程,然后当一个节点收到一半以上节点的选票时,就可以认为它被选为Leader。但是这里投谁还是有讲究的。
所以我们可以考虑一下。例如,当我们选择村长时,我们通常会看到谁有很大的能力,对吧,谁有很大的能力,然后如果能力相似,我们可能会选择更老的,受到高度尊重。幸运的是,在Zookeper集群选举中,当一个节点想要时当决定投票给谁时,将根据两个重要的ID来判断:
- 首先是看事务ID(zxid),任何服务器上的事务ID都是最大的。[对应此场景:
Leader故障,事务请求已提交
】 - 然后,当两个节点事务ID相同时,您将查看节点编号,即存储在myid中的编号,哪个大投资哪个
幸运的是,有了投票标准,你可以开始选举,但在选举中,可能会有不止一轮的投票,就像我们选择村长一样,一般会有多轮的投票,在这种情况下,前一轮的投票,到下一轮,应该成为无效的投票,对吧。
在Zookeeper中,它也有这一轮的概念,即每次投票都有时间限制【syncLimit:集群中的folllower服务器和leader服务器之间的请求和响应能容忍最多的心跳(ticktime的数量)。】,如果当前投票,没有收到反馈,那么等待一段时间,作为加班,这次可以启动下一轮投票,但可能,最后一轮反馈是由于网络延迟问题,这次收到,所以因为现在是下一轮,所以这只能作为无效的投票。
图:投票响应超时,进入下一轮
选举算法好 有了这些选举的标准和规则,就可以开始选举了。选举算法:
- 首先,每个节点都发起选举自己为领导者的投票(自己投票给自己);因为一开始不知道哪个节点的事务ID最大,先给自己一票,然后给其他节点发消息拉票。拉票的时候,就像选举一样,拉票的时候会说自己能力很强,所以这里也是如此。它会把当前节点最大的事务ID带到过去。
- 当其他节点收到拉票请求时,它们将比较发起人的事务ID是否大于其最新的事务ID。如果它们比自己的ID大,最好投票给它,否则它们就不会投票给它。如果事务ID相等,则比较发起人的服务器号码。正如我们前面所说,就像选举一样,首先看看谁有能力,然后看看谁老了。
- 然后,在每一轮投票之后,这取决于是否有任何节点。它获得的票数(包括它自己的)大于集群的一半。如果是这样,这表明该节点已成功竞选并成为领导者节点。如果不超过一半,且领导者未选择,则再次发起投票。
现在我们来看看第一个服务器启动时的leader选举。 让我们来看看这张照片
假设一个 Zookeeper 集群中有5台服务器,id从1到5编号,都是最新启动的,没有历史数据
假设服务器依次启动,我们将分析选举过程:
服务器1启动
服务器1启动,发起选举,服务器1投票,此时服务器1投票,不超过一半,大于或等于3票,选举无法完成。 因此,此时投票结果:服务器1为1。
LOOKING保持服务器1状态。
服务器2启动
服务器2启动并发起选举。服务器1和2分别投票。此时,服务器1发现服务器2的服务ID比自己大,并将选票更改为服务器2。 因此,投票结果:服务器10票,服务器22票。
保持LOOKING状态的服务器1
服务器3启动
服务器3也启动了,同时也发起了选举,服务器1、2、3先投自己一票,然后因为服务器3的服务器id最大,两者更改投票给服务器3;
此时,投票结果为:服务器10票,服务器20票,服务器33票。此时,服务器3的票数已超过一半,服务器3当选为Leader。
服务器1、2更改FOLLOWING,服务器3更改LEADING
服务器4启动
当服务器1、2、3不再是LOOKING时,服务器4启动并加入并发起选举 状态不会改变选票信息。交换选票信息结果:服务器3票,服务器4票。此时,服务器4服从大多数,将选票信息更改为服务器3。
FOLLOWING将服务器4改为FOLOWING。
服务器5启动
和服务器4一样投票给3,此时服务器3共5票,服务器5为0票。
FOLLOWING将服务器5改为FOLOWING。
最终结果:
服务器3是 Leader,状态为 LEADING;其它服务器是 Follower,状态为 FOLLOWING。
好吧,这是服务器初始化开始时的选举过程。
在服务器运行期间 Leader 故障然后,让我们继续看看服务器运行期间的第二个选举过程 Leader 故障。
让我们来看看这个场景:
在 Zookeeper运行期间 Leader 和 follower 各司其职,当有follower时 服务器停机或加入不会影响 Leader,但是一旦 Leader 如果服务器挂了,整个服务器就挂了。 Zookeeper 集群将暂停对外服务,引发新一轮选举。
在初始状态下,服务器3被选为Leader。假设现在服务器3故障停机,此时每个服务器上的zxid可能会有所不同,server1为10,server2为12,server4为10,server5为10。
运行期选举运行期选举与初始状态投票过程基本相似,大致可分为以下步骤:
- 状态变更。Leader 故障后,剩下的folllower节点无法与leader联系。此时,它将将其服务器状态改为looking,然后开始进入leader选举过程。
- 每个Server都会投票。
- 如果其他服务器的数据比自己的新会更改投票,则接收来自各服务器的投票。
- 处理和统计投票,每轮投票结束后统计投票,超过一半可当选。
- 改变服务器状态,宣布当选
好吧,这里我们用这张图来解释更容易理解的点:
1)第一次投票时,每台机器都会投票给自己。
2)然后每台机器都会把自己的投票发给其他机器。如果发现其他机器的zxid比自己大,需要重新投票。比如server1 收到三张票后,我发现server2的xzid是102。pk发现我输了。后来,我果断地选择server2作为老板进行投票。同样,由于从图中可以清楚地看出,服务器2的xzxid是最大的,因此服务器2最终被选为leader服务器。
小结简单来说,通常哪台机器服务器上的数据越新,就越有可能成为领导者。原因也很简单。数据越新,zxid越大,数据恢复越能保证。如果集群中有几个相同最大的zxid,那么服务器id较大的服务器就会成为领导者。
好了,我们就知道leader选举了。非常感谢。
我们将在下一篇文章中介绍ZAB协议和PAXOS算法。请期待。
欢迎关注「慕课网」在官方账号中,我们将始终坚持提供IT圈的优质内容,分享干货知识,共同成长!
本文原创发布于慕课网。 ,请注明转载来源,谢谢合作