Kafka与Zookeeper

【Zookeeper系列】写请求在Leader内事务处理流程

2022-03-07  本文已影响0人  爱打乒乓的程序员

在开始阅读之前,咱们先思考一个问题,Zookeeper是强一致性的吗?还是最终一致性?

先直接给答案哈,Zookeeper是保证顺序最终一致性!但为什么不是强一致性的呢?接下来,带着疑问往下看~

前置知识

在了解Zookeeper保证最终一致性之前,先看下涉及到的关键内容。比如ZK内为了保证事务消息,运用到2PC的思想,实际处理写请求的过程中,会经过Proposal流程Commit流程

2PC(Two-Phase Commit)

2PC即二阶段提交,与二阶段提交相似的,还有三阶段提交。二阶段提交和三阶段提交可以认为是一种一致性协议,保障在分布式系统中数据的一致性,主要用于分布式事务的场景中。

二阶段提交,顾名思义就是分为两个阶段提交请求嘛,其流程可以认为是准备阶段提交阶段

以下是简单的概括,其流程和原理实际上挺复杂的,但为了不跑偏文章的主题,就简单的概括一下2PC是什么。

Zookeeper处理事务流程

写请求事务处理

经过上面的前置知识了解,Zookeeper处理消息的事务流程,主要是Proposal和Commit阶段。

接下来,以文字结合图片的形式,大致了解写请求的过程。

  1. 客户端发送写请求,Leader接收到写请求后,生成Proposal提案且生成全局的zxid,并将Proposal提案写入磁盘事务日志文件。但实际上,为了提高性能,会先将Proposal写入os cache中,再在某时机将os cache中的内容写入磁盘事务文件 【1】写请求发送到Leader的过程.png
  2. 写入Proposal提案后,Leader会广播到每个Follower都独有的FIFO队列,这样的话,就能保证数据的顺序执行;当Follower接收到Proposal后,同样会类似Leader那样为了提高写数据的性能,先写到Follower的os cache中,然后在某时机写入磁盘事务日志文件;当Follower写入Proposal后,会给Leader响应ACK 【2】写请求发送到Leader的过程.png
  3. 当Leader接收到的ACK超过集群的一半,就会认为Proposal提交成功。Leader本地就会执行事务,将数据封装为Znode写到内存中,并发送commit命令给所有Follower,当其它Follower接收到commit命令后,同样会将数据封装为Znode写到内存中。

【3】写请求发送到Leader的过程.png

目前为止,就可以认为写请求处理完毕,客户端可以从Leader读取刚刚的写请求,但如果客户端从Follower读取的话,一定能读取到吗?

这就要回到文章开始的一个思考题,其答案是Zookeeper不能保证强一致性,只能保证顺序的最终一致性。咱们回过头想下写请求的事务处理过程。

当写请求生成的Proposal被广播到每一个Follower,只是先写到os cache或磁盘事务日志文件中,这时候并没有生成Znode写到内存,对于客户端来说是读取不到的;如果Leader发出commit请求的时候,由于网络原因或者Follower短暂的失去与Leader的连接,其实都有可能出现短暂的消息不一致,这是如果客户端请求访问还没生成Znode数据的话,肯定读取不到。所以这就解释了,为什么Zookeeper并不能保证强一致性。

但为什么说Zookeeper能保证顺序最终一致性呢?

这是因为Leader与Follower提交Proposal都是经过FIFO的队列,其保证了数据有序。除此之外,如果Leader提交commit后,Follower没有及时接收到commit,会有其他保障机制,保证最后集群内所有服务器都趋于数据一致。

以上就是写请求落在Leader上的大致经过,如果写请求落在Follower是怎样呢?其实流程上是没什么区别的,只不过是Follower将写请求转发给Leader,由Leader去处理写请求,然后就和上诉的流程一样,最后达到数据最终一致。

如果觉得文章不错的话,麻烦点个赞哈,你的鼓励就是我的动力!对于文章有哪里不清楚或者有误的地方,欢迎在评论区留言~

上一篇下一篇

猜你喜欢

热点阅读