当前位置: 首页 > article >正文

Kafka【十一】数据一致性与高水位(HW :High Watermark)机制

【1】数据一致性

Kafka的设计目标是:高吞吐、高并发、高性能。为了做到以上三点,它必须设计成分布式的,多台机器可以同时提供读写,并且需要为数据的存储做冗余备份。
在这里插入图片描述
图中的主题有3个分区,每个分区有3个副本,这样数据可以冗余存储,提高了数据的可用性。并且3个副本有两种角色,Leader和Follower,Follower副本会同步Leader副本的数据。

一旦Leader副本挂了,Follower副本可以选举成为新的Leader副本, 这样就提升了分区可用性,但是相对的,在提升了分区可用性的同时,也就牺牲了数据的一致性。

我们来看这样的一个场景:一个分区有3个副本,一个Leader和两个Follower。Leader副本作为数据的读写副本,所以生产者的数据都会发送给leader副本,而两个follower副本会周期性地同步leader副本的数据,但是因为网络,资源等因素的制约,同步数据的过程是有一定延迟的,所以3个副本之间的数据可能是不同的。具体如下图所示:
在这里插入图片描述
此时,假设leader副本因为意外原因宕掉了,那么Kafka为了提高分区可用性,此时会选择2个follower副本中的一个作为Leader对外提供数据服务。此时我们就会发现,对于消费者而言,之前leader副本能访问的数据是D,但是重新选择leader副本后,能访问的数据就变成了C,这样消费者就会认为数据丢失了,也就是所谓的数据不一致了。

在这里插入图片描述

为了提升数据的一致性,Kafka引入了高水位(HW :High Watermark)机制,Kafka在不同的副本之间维护了一个水位线的机制(其实也是一个偏移量的概念),消费者只能读取到水位线以下的的数据。这就是所谓的木桶理论:木桶中容纳水的高度,只能是水桶中最短的那块木板的高度。这里将整个分区看成一个木桶,其中的数据看成水,而每一个副本就是木桶上的一块木板,那么这个分区(木桶)可以被消费者消费的数据(容纳的水)其实就是数据最少的那个副本的最后数据位置(木板高度)。

也就是说,消费者一开始在消费Leader的时候,虽然Leader副本中已经有a、b、c、d 4条数据,但是由于高水位线的限制,所以也只能消费到a、b这两条数据。

在这里插入图片描述
这样即使leader挂掉了,但是对于消费者来讲,消费到的数据其实还是一样的,因为它能看到的数据是一样的,也就是说,消费者不会认为数据不一致。
在这里插入图片描述
不过也要注意,因为follower要求和leader的日志数据严格保持一致,所以就需要根据现在Leader的数据偏移量值对其他的副本进行数据截断(truncate)操作。
在这里插入图片描述

【2】HW在副本之间的传递

HW高水位线会随着follower的数据同步操作而不断上涨,也就是说,follower同步的数据越多,那么水位线也就越高,那么消费者能访问的数据也就越多。接下来我们就看一看,follower在同步数据时HW的变化。

首先,初始状态下,Leader和Follower都没有数据,所以和偏移量相关的值都是初始值0,而由于Leader需要管理follower,所以也包含着follower的相关偏移量(LEO)数据。
在这里插入图片描述
生产者向Leader发送两条数据,Leader收到数据后,会更新自身的偏移量信息。

Leader副本偏移量更新:LEO=LEO+2=2

在这里插入图片描述
接下来,Follower开始同步Leader的数据,同步数据时,会将自身的LEO值作为参数传递给Leader。此时,Leader会将数据传递给Follower,且同时Leader会根据所有副本的LEO值更新HW。

在这里插入图片描述

Leader副本偏移量更新:HW = Math.max[HW, min(LeaderLEO,F1-LEO,F2-LEO)]=0

在这里插入图片描述
由于两个Follower的数据拉取速率不一致,所以Follower-1抓取了2条数据,而Follower-2抓取了1条数据。Follower再收到数据后,会将数据写入文件,并更新自身的偏移量信息。

Follower-1副本偏移量更新:
LEO=LEO+2=2
HW = Math.min[LeaderHW, LEO]=0
Follower-2副本偏移量更新:
LEO=LEO+1=1
HW = Math.min[LeaderHW, LEO]=0

在这里插入图片描述
接下来Leader收到了生产者的数据C,那么此时会根据相同的方式更新自身的偏移量信息

Leader副本偏移量更新:LEO=LEO+1=3

在这里插入图片描述
follower接着向Leader发送Fetch请求,同样会将最新的LEO作为参数传递给Leader。Leader收到请求后,会更新自身的偏移量信息。

Leader副本偏移量更新:HW = Math.max[HW, min(LeaderLEO,F1-LEO,F2-LEO)]=1

在这里插入图片描述
此时,Leader会将数据发送给Follower,同时也会将HW一起发送。

在这里插入图片描述

Follower收到数据后,会将数据写入文件,并更新自身偏移量信息

Follower-1副本偏移量更新:
LEO=LEO+1=3
HW = Math.min[LeaderHW, LEO]=1
Follower-2副本偏移量更新:
LEO=LEO+1=2
HW = Math.min[LeaderHW, LEO]=1

在这里插入图片描述
因为Follower会不断重复Fetch数据的过程,所以前面的操作会不断地重复。最终,follower副本和Leader副本的数据和偏移量是保持一致的。
在这里插入图片描述

上面演示了副本列表ISR中Follower副本和Leader副本之间HW偏移量的变化过程,但特殊情况是例外的。比如当前副本列表ISR中,只剩下了Leader一个副本的场合下,是不需要等待其他副本的,直接推高HW即可。


http://www.kler.cn/a/292599.html

相关文章:

  • 现代无线通信接收机架构:超外差、零中频与低中频的比较分析
  • 前端面试笔试(二)
  • react-redux useSelector钩子 学习样例 + 详细解析
  • 【Visual Studio】使用VS调试(Debug)
  • Ubuntu配置阿里云docker apt源
  • 学习记录:js算法(九十二):克隆图
  • 企业财务流程优化的财税自动化解决方案
  • Python知识点:如何使用Pytest进行单元测试
  • JVM系列(十) -垃圾收集器介绍
  • OpenObserve云原生可观测平台本地Docker部署与远程访问实战教程
  • KDD2024参会笔记-Day1
  • Core ML
  • 基于.NET6的WPF基础总结(上)
  • CSS学习9
  • RPC框架-RMI
  • OpenHarmony应用开发( Beta5版)利用native方式实现跨线程调用最佳实践
  • nvidia-cuda-tensorrt-cudnn下载网站
  • 【golang】使用container/heap官方包实现一个优先队列
  • 鼠标在虚拟机virtualbox里面不显示/消失,如何解决?
  • Stable Diffusion训练LoRA模型参数详细说明(阿里巴巴堆友AI)
  • List、Set、Map中的方法使用、Stream流、Collections工具类
  • 如何使用 Lua 脚本进行更复杂的网络请求,比如 POST 请求?
  • 一个开源、注重隐私且支持自托管的网站分析工具
  • 数据结构 哈希表 五大排序算法 二分查找(折半查找)
  • GitHub精选|8 个强大工具,助力你的开发和探究工作
  • Android studio 导出 release 版本的 .aar 文件