kafka系统的CAP保证

news2024/12/1 0:34:19

kafka系统的CAP保证

CAP理论作为分布式系统的基础理论,它描述的是一个分布式系统在以下三个特性中:

  • 一致性(Consistency)
  • 可用性(Availability)
  • 分区容错性(Partition tolerance)
    最多满足其中的两个特性。也就是下图所描述的。分布式系统要么满足CA,要么CP,要么AP。无法同时满足CAP。
    分区容错性:指的分布式系统中的某个节点或者网络分区出现了故障的时候,整个系统仍然能对外提供满足一致性和可用性的服务。也就是说部分故障不影响整体使用。事实上我们在设计分布式系统时都会考虑到bug,硬件,网络等各种原因造成的故障,所以即使部分节点或者网络出现故障,我们要求整个系统还是要继续使用的(不继续使用,相当于只有一个分区,那么也就没有后续的一致性和可用性了)
    可用性:一直可以正常的做读写操作。简单而言就是客户端一直可以正常访问并得到系统的正常响应。用户角度来看就是不会出现系统操作失败或者访问超时等问题。
    一致性:在分布式系统完成某写操作后任何读操作,都应该获取到该写操作写入的那个最新的值。相当于要求分布式系统中的各节点时时刻刻保持数据的一致性。

分区副本机制

kafka 从 0.8.0 版本开始引入了分区副本;引入了数据冗余
用CAP理论来说,就是通过副本及副本leader动态选举机制提高了kafka的 分区容错性和可用性
但从而也带来了数据一致性的巨大困难!

分区副本的数据一致性困难

kafka让分区多副本同步的基本手段是: follower副本定期向leader请求数据同步!
既然是定期同步,则leader和follower之间必然存在各种数据不一致的情景!

  • 问题1:分区副本间动态不一致

在这里插入图片描述

  • 问题2:消费者所见不一致
    如果此时leader宕机,follower1或follower2被选为新的leader,则leader换届前后,消费者所能读取到的数据发生了不一致;

在这里插入图片描述

  • 问题3:分区副本间最终不一致
    在这里插入图片描述

一致性问题解决方案(HW)

动态过程中的副本数据不一致,是很难解决的;
kafka先尝试着解决上述“消费者所见不一致”及“副本间数据最终不一致”的问题;

核心思想
- 在动态不一致的过程中,维护一条步进式的“临时一致线”(既所谓的High Watermark);
- 高水位线HW = ISR副本中最小LEO(副本的最大消息位移+1); 
- 底层逻辑就是:offset<HW的message,是各副本间一致的且安全的!
  • 解决“消费者所见不一致” (消费者只允许看到HW以下的message)
  • 解决“分区副本数据最终不一致” (follower数据按HW截断)
    在这里插入图片描述

HW方案的天生缺陷

如前所述,看似HW解决了“分区数据最终不一致”的问题,以及“消费者所见不一致”的问题,但其实,这里面存在一个巨大的隐患,导致:

  • “分区数据最终不一致”的问题依然存在
  • producer设置acks=all后,依然有可能丢失数据的问题
    在这里插入图片描述

第一次fetch请求,分leader端和follower端:
leader端:

  1. 读取底层log数据。
  2. 根据fetch带过来的offset=0的数据(就是follower的LEO,因为follower还没有写入数据,因此LEO=0),更新remote LEO为0。
  3. 一轮结束后尝试更新HW,做min(leader LEO,remote LEO)的计算,结果为0。
  4. 把读取到的三条log数据,加上leader HW=0,一起发给follower副本。
    follower端:
  5. 写入数据到log文件,更新自己的LEO=3。
  6. 更新HW,做min(leader HW,follower LEO)的计算,由于leader HW=0,因此更新后HW=0。
    可以看出,第一次fetch请求后,leader和follower都成功写入了三条消息,但是HW都依然是0,对消费者来说都是不可见的,还需要第二次fetch请求。

第二次fetch请求,分leader端和follower端:
leader端:

  1. 读取底层log数据。
  2. 根据fetch带过来的offset=3的数据(上一次请求写入了数据,因此LEO=3),更新remote LEO为3。
  3. 尝试更新HW,做min(leader LEO,remote LEO)的计算,结果为3。
  4. 把读取到的log数据(其实没有数据),加上leader HW=3,一起发给follower副本。
    follower端:
  5. 写入数据到log文件,没有数据可以写,LEO依然是3。
  6. 更新HW,做min(leader HW,follower LEO)的计算,由于leader HW=3,因此更新后HW=3。
    这个时候,才完成数据的写入,并且分区HW(分区HW指的就是leader副本的HW)更新为3,代表消费者可以消费offset=0,1,2的三条消息了,上面的过程就是kafka处理消息写入和备份的全流程。

HW会产生数据丢失和副本最终不一致问题

在这里插入图片描述

如上图所示:

  • 状态起始:最新消息c已同步,但是水位线还没开始同步
  • 在此时leader崩溃(即 follower 没能通过下一轮请求来更新 HW 值)
  • follower成为了leader,会自动将 LEO 值调整到之前的 HW 值,即会进行日志截断
  • 然后,原来的leader重启上线,会向新的leader发送请求请求,收到 fetch 响应后,拿到 HW 值,并更新本地 HW 值,发现我也要截取,悲剧发生了,数据丢了
    在这里插入图片描述

如上图所示:

  • 状态起始:最新消息c已同步,但是水位线还没开始同步
  • 在此时leader崩溃(即 follower 没能通过下一轮请求来更新 HW 值)
  • follower成为了leader,会自动将 LEO 值调整到之前的 HW 值,即会进行日志截断
  • 在截断日志之后,也就是这个d被截断了之后,我又加了一条数据是e
  • 然后,原来的leader重启上线,会向新的leader发送请求请求,收到 fetch 响应后,拿到 HW 值,并更新本地 HW 值,发现我的数据和leader的数据一样,好的,我就不用截取了,我更新HW就好了,就这样,一个新的悲剧又发生了,数据不一致了

Leader-Epoch机制的引入

为了解决 HW 更新时机是异步延迟的,而 HW 又是决定日志是否备份成功的标志,从而造成数据丢失和数据不一致的现象,Kafka 引入了 leader epoch 机制;
在每个副本日志目录下都创建一个 leader-epoch-checkpoint 文件,用于保存 leader 的 epoch 信息;
leader-epoch的含义
如下,leader epoch 长这样:

在这里插入图片描述

它的格式为 (epoch offset),epoch指的是 leader 版本,它是一个单调递增的一个正整数值,每次 leader 变更,epoch 版本都会 +1,offset 是每一代 leader 写入的第一条消息的位移值,比如:
(0,0)
(1,300)
以上第2个版本是从位移300开始写入消息,意味着第一个版本写入了 0-299 的消息。
leader epoch 具体的工作机制

  • 当副本成为 leader 时:
    这时,如果此时生产者有新消息发送过来,会首先更新leader epoch 以及LEO ,并添加到 leader-epoch-checkpoint 文件中;
  • 当副本变成 follower 时:
    发送LeaderEpochRequest请求给leader副本,该请求包括了follower中最新的epoch 版本;
    leader返回给follower的响应中包含了一个LastOffset,如果 follower last epoch = leader last epoch(纪元相同),则 LastOffset = leader LEO,否则取follower last epoch 中最小的 leader epoch 的 start offset 值;

follwer 拿到 LastOffset 之后,会对比当前 LEO 值是否大于 LastOffset,如果当前 LEO 大于 LastOffset,则从 LastOffset 截断日志;
follower 开始发送 fetch 请求给 leader 保持消息同步。
leader epoch 如何解决HW的备份缺陷

  • 解决数据丢失和数据不一致的问题
    在这里插入图片描述
    如上图所示:
    follower当选leader后,收到纪元消息,发现 LastOffset等于当前 LEO 值,故不用进行日志截断。
    follower重启后同步消息,发现自己也不用截取,数据一致,齐活儿
    当然,如果说后来增加消息以后,也不需要截取,直接同步数据就行(当ack=-1)

LEO/HW/LSO等相关术语速查

LEO:(last end offset)就是该副本中消息的最大偏移量的值+1 ;
HW:(high watermark)各副本中LEO的最小值。这个值规定了消费者仅能消费HW之前的数据;
LW:(low watermark)一个副本的log中,最小的消息偏移量; 应该是和log里面的偏移量有关系
LSO:(last stable offset) 最后一个稳定的offset;对未完成的事务而言,LSO 的值等于事务中第一条消息的位置(firstUnstableOffset),对已完成的事务而言,它的值同 HW 相同;

在这里插入图片描述

LEO与HW 与数据一致性密切相关;
在这里插入图片描述
如图,各副本中最小的LEO是3,所以HW是3,所以,消费者此刻最多能读到Msg2;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/619586.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Window winget 包管理工具安装踩坑记录

一、简介 想在 window 上安装一个好用的包管理工具&#xff0c;mac 上用 homebrew, window 则考虑再三&#xff0c;使用官方提供的 winget。 winget 官方使用文档。 二、安装流程与踩坑记录 按 win x&#xff0c;选择 Powershell&#xff08;管理员&#xff09; 方式打开 c…

【严重】Linux kernel ksmbd 模块远程代码执行漏洞

漏洞描述 ksmbd 是 Linux kernel 的一个模块&#xff0c;用于提供 SMB&#xff08;Server Message Block&#xff09;文件共享协议的支持&#xff0c;SMB2_TREE_DISCONNECT 命令用于断开客户端与服务器之间的文件共享连接。 Linux kernel 受影响版本中&#xff0c;由于 ksmbd…

SpringBoot Filter使用

filter就是其他框架中的中间件,在SpringBoot启动时有很多默认加载的Filter 例如: characterEncodingFilterhiddenHttpMethodFilterhttpPutFormContentFilterrequestContextFilter Filter存在一个优先级, 数值越小越靠前 这有两个常量用来表顺顺序 Ordered.HIGHEST_PRECEDENCE…

webpack处理样式资源(css less sass scss)

Webpack 本身是不能识别样式资源的&#xff0c;所以我们需要借助 Loader 来帮助 Webpack 解析样式资源 一、处理css样式资源 去项目根目录新建css文件夹&#xff0c;在css文件夹下新增index.css文件&#xff0c;内容如图&#xff1a; 在src-main.js中引入css->index.css文…

各个AI模型写2023年广东高考作文大比拼

今天是一年一度的高考开始的日子&#xff0c;寒窗苦读十二年&#xff0c;剑指今朝。 作为过来人&#xff0c;当年的高考场景还历历在目。这里先预祝各位莘莘学子&#xff0c;高考正常发挥&#xff0c;旗开得胜&#xff0c;马到功成&#xff0c;考上心中理想的大学。 今天早上是…

《精通特征工程》学习笔记(3):特征缩放的效果-从词袋到tf-idf

1.TF-IDF原理 tf-idf 是在词袋方法基础上的一种简单扩展&#xff0c;它表示词频 - 逆文档频率。tf-idf 计算的不是数据集中每个单词在每个文档中的原本计数&#xff0c;而是一个归一化的计数&#xff0c;其中每个单词的计数要除以这个单词出现在其中的文档数量。 词袋bow(w, …

面向对象的特征三:多态性

1.多态性的理解&#xff1a; 可以理解为一个事物的多种形态。 2.何为多态性&#xff1a; 对象的多态性&#xff1a;父类的引用指向子类的对象&#xff08;或子类的对象赋给父类的引用&#xff09; 可以直接应用在抽象类和接口上 举例&#xff1a;Person p new Man(); O…

场景营销解密:出海品牌在全球市场的差异化策略

品牌出海是企业扩大国际市场份额、实现全球化发展的必经之路。然而&#xff0c;面对激烈的全球竞争和多样化的消费者需求&#xff0c;仅仅依靠传统的广告宣传手段已经无法满足品牌推广的需求。而场景营销则通过创造具有情境感的消费体验&#xff0c;更好地满足了消费者的参与需…

手写分布式事务的一种回滚方案。

1&#xff1a;项目架构 我一个朋友的公司基于实际业务的考虑&#xff0c;选择了多个单体项目来组建成一个分布式系统。&#xff08;对于目前来说分布式的系统最好采用微服务的架构来实现项目搭建。但基于许多客户只能采用内网的使用&#xff0c;微服务反而会影响项目的复杂度&a…

STM32ADC学习(一)

ADC 模拟/数字转换器 常见ADC类型 并联比较型工作示意图 ADC的特性参数 分辨率&#xff1a;ADC能辨别的最小模拟量&#xff0c;用二进制位数来表示。例如3.3V&#xff0c;12位&#xff0c;能辨别的最小模拟量就是&#xff1a;&#xff08;3.3/4096&#xff09;转换时间&#x…

【面试题HTTP中的两种请求方法】GET 和 POST 有什么区别?

GET 和 POST 有什么区别&#xff1f; 1.相同点和最本质的区别1.1 相同点1.2 最本质的区别 2.非本质区别2.1 缓存不同2.2 参数长度限制不同2.3 回退和刷新不同2.4 历史记录不同2.5 书签不同 总结代码示例 GET 和 POST 是 HTTP 请求中最常用的两种请求方法&#xff0c;在日常开发…

练手必备,20个Python实战项目含源代码

“读”代码是不能给你带来任何收益的&#xff0c;正如“读书”一样&#xff0c;如果在读的时候你不琢磨&#xff0c;保管你读完仨月准忘了一大半。真正需要的是去“试”代码&#xff0c;动手去调调代码&#xff0c;改改这改改那&#xff0c;看看把A变成B这个代码的结果会有什么…

c#使用RSA公钥解密

文章目录 前言一、解密函数1、上代码&#xff01;2、传入的字符串不是base64格式 二、在线验证总结 前言 新项目对接第三方&#xff0c;会把用户信息反正url里面rsa加密传过来&#xff0c;拿到后我解密出用户数据&#xff0c;只给了一个公钥&#xff0c;他们用的java、我用的c…

SpringBoot生成RESTful API文档

由于我一开始学习的SpringBoot是3以上版本&#xff0c;所以我这里用到的也是支持和SpringBoot3能够整合的SpringDoc 这里先说一下&#xff0c;其实SpringDoc就是Swagger3版本&#xff0c;我一开始整合的2版本&#xff0c;比较麻烦况且最后SpringBoot程序都启动不了了&#xff0…

怎样书写专业的落地性能测试计划?

目录 引言 什么是性能测试计划 性能测试计划包含的内容 背景 性能目标 压测范围 启停准则 性能指标 系统架构图 压测前准备 工具准备 数据准备 性能设计 监控设计 项目组织架构 成果输出 项目风险分析 引言 测试计划是软件测试流程中的一个重要步骤&#xff0c;它涉及到对软件…

面向教育行业的MDM(移动设备管理)解决方案

什么是面向教育的MDM 学校和教育机构的移动设备管理 &#xff08;MDM&#xff09; 通过将智能设备配置为适合教育用途&#xff0c;支持通过这些设备进行学习。面向教育的 MDM 解决方案允许组织的 IT 管理员或教学人员管理有助于学习的设备&#xff0c;如智能手机、平板电脑、笔…

十三、输出多个立方体并深度测试

第一部分概念 1&#xff09;由来&#xff1a; 深度测试&#xff1a;opengl的深度测试是指在片段着色器执行之后&#xff0c;利用深度缓冲所保存的深度值决定当前片段是否被丢弃的过程。 深度缓冲区和颜色缓冲区是差不多的&#xff0c;有相同的宽高度&#xff0c;并且一般在窗…

实验篇(7.2) 06. 通过安全隧道访问远端内网服务器 (FortiClient-SSL) ❀ 远程访问

【简介】直接映射服务器到公网&#xff0c;没有验证不安全&#xff1b;通过Web浏览器访问远程内网服务器&#xff0c;有验证也安全&#xff0c;但是支持的协议太少。那有没有即安全&#xff0c;又能支持所有协议的访问方法呢&#xff1f;我们来看看SSL VPN的隧道模式。 实验要求…

智能动环监控系统,实时排查机房安全隐患

动环监控系统又称机房动环、机房动力环境监控系统、动环监控等&#xff0c; 是指对各机房的动力、环境、安防进行集中监测。可对监控系统、设备、安全运行状态进行实时监测、通过统计和处理相关数据&#xff0c;及早发现故障&#xff0c;及时通知运维人员处理&#xff1b;实现机…

员工工作服穿戴AI识别算法 yolov5

员工工作服穿戴AI识别算法是基于yolov5python网络模型人工智能技术&#xff0c;员工工作服穿戴AI识别算法对现场人员的工作服穿戴情况进行实时监控&#xff0c;并对违规情况将自动发出警报。我们选择当下YOLO卷积神经网络YOLOv5来进行火焰识别检测。现版本的YOLOv5每个图像的推…