技术大佬问我,kafka是如何做到数据的高可靠的(下)

佩琪: 大佬,你昨天给讲了kafka数据高可靠 主从同步的概念和过程;但还留了个尾巴,kafka主从同步两阶段协议里存在的问题还没有讲了

技术大佬 : (幸亏上次到饭点,否则就尬死了,这个佩琪问题真多,没办法还需要继续装下去)

技术大佬 : 在主从同步时,如果只靠HW和LEO,在某些特殊的情况下 ,确实存在两种问题 。一种是 数据会丢失 ;另外一种是数据可能会不一致

佩琪: 什么样的特殊条件下了?

技术大佬 : 准确说是在 min.insync.replicas=1 这种特殊设置下(级leader partition写入消息到本地,就代表了"消息已提交")

佩琪: 那在这种情况下,依靠HW和LEO的主从同步,是如何导致数据丢失的呢?

技术大佬 : 咱们看图说话?(资料来自于 kafka KIP官方文档)

技术大佬 : 还记得上次讲的《 kafka是如何做到数据的高可靠的》里面数据同步过程吗? 从上面的图可看出

  1. (A) 在同步的第一阶段,从 (B)拉取m2消息写入到本地文件系统
  2. (A) 突然宕机了(还来不及发送第二次请求 获取leader HW)
  3. 此时副本(A)重新启动。它将其日志截断至高水位线 并向领导者 (B) 发出获取请求。
  4. (B) 然后失败,A 成为新的领导者。消息m2已经永久丢失(无论B是否回来)。

技术大佬 : 从上面的过程 可看到 这种数据的丢失,是由于kafka 在进行重启恢复时,由截断日志的机制和 min.insync.replicas=1的情况下,共同造成的。

佩琪: min.insync.replicas=1的情况下,数据可能会丢失,这我还能理解,毕竟min.insync.replicas=1 表示只要有一个副本把消息写入成功,就表示消息已提交了。比如leader partition 写入消息到文件系统成功,就表示已提交;但如果leader partition 所在的broker都宕机了,那么在为1的条件下,kafka是不能保证leader切换后, 这种情况消息不丢的。

佩琪: 那依靠HW和LEO,是如何导致数据不一致的呢,我觉得这个才是最要命的?

技术大佬 : 确实,如果多个分区之间的数据都不一致了,问题确实较大。咋们还是看图说话?

  1. 在min.isr=1的情况下,(A)和(B)同时宕机了
  2. (B) 先恢复,成为了leader,接受消息M3,HW变为了2
  3. (A)在恢复,然后截取消息日志,发现HW和LEO相同,就不截取了
  4. 此时在相同的消息位置1上,出现了不同的消息内容

佩琪: min.insync.replicas=1的情况下,确实恼火,有啥解决方法了?

技术大佬 : 有的,kafka 引入了Leader Epoch 的概念来解决这两个问题 。

技术大佬 : Leader Epoch 包含两部分数据。

一个是 epoch: 表示一个单调递增的版本号。每当leader 发生变更(比如重选变更)时,都会增加;

一个是 start offset: 在新 Leader Epoch 中写入日志的第一个偏移量的消息位置。

这部分数据 每个副本集都有,并且还写入了本地文件系统里。

佩琪: 那 Leader Epoch 是如何解决数据不一致的了?

技术大佬 : 咋们还是看图说话?

  1. (A)和(B)在宕机前;根据Leader Epoch 规则。Leader Epoch为0 ,start offset 为0
  2. 当 (B) 由于宕机重启后,(B) 成为了领导者;此时Leader Epoch为1 ,start offset为1
  3. (B) 接受了消息M3;
  4. (A)此时重启进行恢复;变成了follower,它在截断日志前会发送一个LeaderEpoch 的请求(参数里带上本分区的 leader epoch 0)给当前的领导者;
  5. 当前领导者 (B) 一查 Leader Epoch为0的log End offset (请求的leader epoch+1 的start offset )为1;然后返回给 (A)
  6. (A) 拿到返回值,发现leader epoch 为0 的 log end offset为1 ,比自己本地的log end offset 2 还小;那就以leader返回的为准吧;把1 以及后面位置的日志都给截断了;这样在lead epoch为0时,(A)和(B)分区的日志数据保持了一致
  7. 为了追赶数据,folower(A) 再从leader(B)请求同步数据;把m3消息同步到本地中。最终 (A)和(B)保持了数据同步。

总结

在min.insync.replicas=1 + kafka只根据HW截断日志的情况下;主从分区,会存在已提交消息,在leader切换时;会丢失数据的情况;或者数据不一致的情况;

在min.insync.replicas=1的情况下,leader分区切换,导致已提交消息丢失,这个还能理解;谁让你设置的为1了;但是在这种情况下,发生leader 分区切换,导致数据不一致,却是不能允许的。

kafka已在0.11.0.0 版本中,通过引入 Leader Epoch的概念,解决了上述场景中的问题;降低了此种情况下,leader分区切换导致的数据丢失和不一致的问题。但在min.insync.replicas=1的情况下;仍然存在leader 分区切换后,已提交消息会丢失的问题。

如果要提高broker端消息的可靠性,可参考:《kafka 消息"零丢失"》

原创不易,请 点赞,留言,关注,收藏 4暴击^^

参考资料:

cwiki.apache.org/confluence/...

相关推荐
Li_Ning211 小时前
【vue3】实现pdf在线预览的几种方式
前端·pdf
水瓶丫头站住1 小时前
Qt的QTableWidget样式设置
前端·qt
2401_897605651 小时前
AI前端开发技能提升与ScriptEcho:拥抱AI时代的前端开发新范式
前端·人工智能
老K(郭云开)5 小时前
最新版Edge浏览器集成ActiveX控件之金山WpsDocFrame控件
前端·javascript·chrome·3d·中间件
Anyexyz5 小时前
Windows 11 卸载 Edge
前端·windows·edge
放学-别走6 小时前
基于Django以及vue的电子商城系统设计与实现
vue.js·后端·python·django·毕业设计·零售·毕设
一路向前的月光7 小时前
React(6)
前端·javascript·react.js
众智创新团队7 小时前
singleTaskAndroid的Activity启动模式知识点总结
前端
Asthenia04127 小时前
排序算法稳定性解析与Java实现分析
后端
祁许8 小时前
【Vue】打包vue3+vite项目发布到github page的完整过程
前端·javascript·vue.js·github