Zookeeper集群如何实现强一致性和高可用,集群数据同步过程

在分布式系统中,通常会面临如下问题:

  • 分布式协调:在分布式环境下,多个节点需要协同工作,确保多个服务之间数据的一致性以及系统的可靠性。

  • 分布式锁:在分布式系统中,多个节点可能需要同时访问共享资源,为了防止竞争条件和数据不一致,需要引入分布式锁机制。

  • 配置管理:在分布式系统中,多个节点需要共享某些配置或数据,并且这些配置需要动态更新。

  • 服务发现:在分布式系统中,节点之间需要互相发现,以便进行通信和协作,尤其是在动态扩展或缩减节点时。

  • 故障恢复:在分布式环境下,单个节点可能会发生故障,因此系统需要具有一定的容错机制,以保证整体系统的可用性。

使用Zookeeper对分布式系统进行管理,可以很大程度上解决解决上述问题,其中依赖Zookeeper集群提供的强一致性策略,可以解决分布式协调中数据之间保持一致的问题。

一致性策略分为

强一致性、线性一致性、因果一致性、最终一致性、弱一致性、读己之所写一致性、会话一致性以及单调读一致性。

其中,强一致性是保证的是所有的写操作都被严格按顺序应用到系统中,所有节点在任何时间点上都能看到相同的数据状态。这意味着,当一个客户端在提交写操作后,所有后续的读操作都能看到这个写操作的结果。

ZooKeeper 实现强一致性主要依赖于 ZAB 协议(ZooKeeper Atomic Broadcast),其类似于paxos算法,这是一种专门为 ZooKeeper 设计的分布式一致性协议。那么他是如何实现强一致性的呢?

集群数据同步流程

1. leader节点统一处理写请求

在Zookeeper集群中,只有leader节点能够处理写操作,其他的follower节点都只能处理读操作,但其并不是不能接受写请求,当接收到写操作的请求时,follower节点会讲这个请求转发给leader节点来处理。

2. 生成并广播提案

Leader节点在接受到写请求后,会生成将写请求先转化成提案,并赋予zxid,然后将这份提案广播给所有的Follower节点。

3. Follower节点确认提案

Follower在接受到Leader节点的提案后,会确认当前提案的zxid是不是正确的。如果正确,则会保存当前提案的zxid,并且执行提案的事务操作但不提交,并返回确认消息ACK,等待Leader再次发送消息时,提交事务更改。

在ZooKeeper中,每个写操作(提案)都会被分配一个递增的事务ID,称为zxid。这个zxid用来标识提案的顺序,确保所有节点按照相同的顺序应用这些操作,以维持数据的一致性,而Follower就根据zxid来确认当前提案是否是期待的下一次提案,已确保事务执行的正确顺序,防止因写操作顺序不一致导致数据差异,具体规则如下:

  1. 接收提案 :当Follower节点收到一个提案时,它首先会检查这个提案的zxid

  2. 处理过期提案 :如果这个提案的zxid比Follower当前已经处理的最新zxid要小,说明这个提案是过期的,可能由于网络延迟或其他原因延迟到达。为了防止数据回滚(即不正确地应用旧的、更早的数据),Follower会直接忽略这个提案,不会保存或执行它。

  3. 处理未来提案 :如果Follower收到的提案zxid比它当前期望的zxid要大,这意味着一些提案在传输过程中丢失了或尚未到达。为了保持数据一致性,Follower会先保存这个提案,但不会立即执行。它会等待缺失的提案到达,并在提案顺序完整时,按顺序执行所有提案。

  4. 读请求处理:在等待缺失提案的过程中,Follower可能暂时无法提供最新的数据。为了避免返回不一致的数据,Follower会将接收到的读请求转发给Leader节点。Leader拥有最新的提交状态,因此能够返回最准确的数据。

4. Leader节点返回成功消息

当Leader节点在接受到一半以上的Follower节点的确认消息后,其就认为当前集群已经可以同步所有写操作,Leader就会通知所有从节点本次提案通过,从节点接收到这个消息后就会提交提案中的事务操作的结果,并且Leader此时会返回给客户端操作成功的响应。

整个流程比较好理解,但不好理解的是整个流程的意义是什么?

意义

1. 高可用

高可用比较好理解,任何中间件的集群模式都是具有高可用的作用,其同步所有数据到每个节点,可以防止因为Leader节点的意外宕机导致导致数据丢失,尤其是在zookeeper这样一个强一致性的要求下,节点之间数据差异的恢复速度极快,数据丢失概率极低。

zookeeper采用提案和确认提案的方式可以确保数据同步中,一半以上的节点都是可以正常接收提案并执行事务的。

当出现网络分区的问题时,一半以上的确认机制也可以使分区后的多个区域中,最多只有一个区域可以执行事务,这样可以防止两个leader同时执行不同的事务导致脑裂。

2. 强一致性

Zookeeper等待大多数节点预先执行完事务操作后返回给客户端成功响应,并且同时给Follower节点发送提案通过的消息,使其提交提案中的事务更改。通过这一过程,Zookeeper大大减少了客户端接收到成功响应到数据同步之间的时间,实现近乎强一致性,不过由于网络速度具有差异,肯能会有一定延迟。如果强行实现一致性,势必会极大的影响性能。

如果对于一致性有着极其严谨的要求,可以在获取数据之前执行sync指令,这个指令会从Leader拉取日志,同步数据,以达到数据最新的目的。

相关推荐
jerry6094 小时前
7天用Go从零实现分布式缓存GeeCache(改进)(未完待续)
分布式·缓存·golang
古人诚不我欺5 小时前
jmeter常用配置元件介绍总结之分布式压测
分布式·jmeter
星染xr7 小时前
kafka 生产经验——数据积压(消费者如何提高吞吐量)
分布式·kafka
东方巴黎~Sunsiny7 小时前
如何监控Kafka消费者的性能指标?
分布式·kafka
飞升不如收破烂~8 小时前
kafka
分布式·kafka
ggaofeng8 小时前
通过命令学习k8s
云原生·容器·kubernetes
龙哥·三年风水9 小时前
群控系统服务端开发模式-应用开发-前端个人信息功能
分布式·vue·群控系统
小码哥呀10 小时前
RabbitMQ集群搭建
分布式·rabbitmq
材料苦逼不会梦到计算机白富美10 小时前
golang分布式缓存项目 Day6 防止缓存击穿
分布式·缓存·golang
qq_道可道12 小时前
K8S升级到1.24后,切换运行时导致 dind 构建镜像慢根因定位与解决
云原生·容器·kubernetes