专栏首页shysh95Kafka基于HW备份恢复弊端分析(III)

Kafka基于HW备份恢复弊端分析(III)

上节中我们已经讲述了关于follower副本的同步机制,并且我们提到了基于HW的备份恢复是有缺陷的。在本节中我们会阐述弊端的原因,并且讲解kafka为了解决问题从而引入了Lead Epoch的概念。

关于基于HW的备份主要会产生两种问题:

  • 数据丢失
  • 数据不一致

下面的问题讲解基于服务端min.insync.replicas值为1,该值为,表示只要Leader接收生产者请求并将消息成功写入了log日志,就会通知客户端消息写入成功,不用在乎ISR中的其他follower副本。

数据丢失

下图是一张关于数据丢失的状态图,下面讲述一下到底发生了什么导致了数据的丢失。

从图中,我们可以看出初始状态,leader A和follower B底层都写入两条日志,只不过leader A的HW已经更新为1,但是follower B的HW为0(因为follower的HW的更新需要经历两次fetch数据请求,这种状态说明follower B只进行了一次fetch数据请求)

假设现在follower没有进行第二次fetch数据请求(图中给的原因假设是重启),并且leader A中由于某种原因发生了宕机,此时当follower B重启之后由于leader A已经宕机所以顺理成章当选leader,B当选leader以后发现自己的HW值为0,于是将offset为1的消息进行删除,同时将LEO的值更新为1(下一次写入消息将会从offset 1开始,此时原来offset=1的消息丢失)。

当A重新启动以后,也会进行日志截断,然后调整HW的值为0。此时offset=1的消息则完全丢失。

数据不一致

下面这张图是数据不一致的状态图,下面讲解一下数据不一致的过程中集群中的leader和follower到底发生了哪些变化。

初始状态为Leader A和Follower B都成功写了第一条日志,并且Leader已经写入了第二条日志。假设此时Follower B来发起fetch数据请求同步第二条日志,由于此时Follower B携带的LEO值为1,当Leader A收到fetch数据请求时,将自己关于的B的RemoteLEO改为1,并且更新自身的HW值为1,然后返回数据给Follower B。

就在这时,很不幸B发生了宕机,并没有收到响应,与此同时LeaderA也发生了宕机。但在重启的过程中,B先恢复,于是B成为Leader(HWL值更新为0,LEO值更新为1),此时A依旧还没恢复重启。

假设就在此时生产者产生了一条消息,于是B将其写入低层log,并且更新了自身的HW为1,LEO为2。一切看似正常,此时A成功重启,发现分区Leader的HW为1,自身的HW也为1,因此不做更新,不进行日志截断。于是,Leader B和Follower A的offset=1存储的消息是不一致的。

改进之道

由于基于HW的备份恢复机制会产生上述两种问题,因此Kafka在0.11.0.0版本之后引入Lead Epoch的解决上述问题。

Lead Epoch其实就是在Leader Broker上单独开辟了一组缓存,来记录(epoch, offset)这组键值对数据,这个键值对会被定期写入一个检查点文件。Leader每发生一次变更epoch的值就会加1,offset就代表该epoch版本的Leader写入的第一条日志的位移。当Leader首次写底层日志时,会在缓存中增加一个条目,否则不做更新。

后面这一块会出一个源码分析,这里就不再展开叙述。源码会讲解关于Leader Epoch的数据结构,以及详细的更新过程。

本文分享自微信公众号 - shysh95(shysh95),作者:shysh95

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Kafka消息规范

    Kafka作为一个消息队列,有其自己定义消息的格式。Kafka中的消息采用ByteBuf,之所以采用ByteBuf这种紧密的二进制存储格式是因为这样可以节省大量...

    shysh95
  • Kafka副本同步(II)

    在上节中,我们讲述了ISR,如何判断段follower副本与leader副本同步以及相关概念(HW、LEO),那么今天这节我们来看一下follower副本与le...

    shysh95
  • JVM-解密Java对象

    在Java程序运行过程中时时刻刻都有对象被创建出来,对象的创建方式有很多种,最常见的就是new,其次还有clone和反序列化。下面我们一起来解密对象的创建、内存...

    shysh95
  • 渣电脑也能玩VR游戏?Steam VR推出分辨率自动优化功能

    VRPinea
  • 『算法理论学』人脸姿态估计算法介绍

    人脸姿态估计算法,主要用以估计输入人脸块的三维欧拉角。一般选取的参考系为相机坐标系,即选择相机作为坐标原点。姿态估计可用于许多业务场景,比如在人脸识别系统的中,...

    小宋是呢
  • CentOS6中利用iptables实现NAT转发和端口映射

    1、CentOS6服务器双网卡,eth0:192.168.31.25/24可以通过外网出口路由器上网,eth1:172.16.10.1/24用于与内网网段172...

    yuanfan2012
  • faster rcnn:assert (boxes[:, 2] >= boxes[:, 0]).all()分析塈VOC2007 xml坐标定义理解

    在进行faster rcnn训练的时候,报了一个断言错误 File “/py-faster-rcnn/tools/../lib/datasets/imdb.p...

    用户1148648
  • 书单丨读了这5本书,架构升级之路不迷茫!

    互联网架构不断演化,经历了从集中式架构到分布式架构,再到云原生架构的过程。云原生因能解决传统应用升级缓慢、架构臃肿、无法快速迭代等问题而成了未来云端应用的目标。

    博文视点Broadview
  • 解决pymysql cursor.fetchall() 获取不到数据的问题

    用 2 的写法报错之后,一度怀疑是数据库出了问题。不服气用pycharm 的watch功能进行调试,更是错上加错。

    砸漏
  • Golang语言社区--【游戏服务器知识】多线程并发

    引言:上篇文章说到了多进程并发式的服务端模型,如上一篇文章所述,进程的频繁创建会导致服务器不堪负载,那这一篇博客主要讲述的是线程模型和线程池的方式来提高服务端的...

    李海彬

扫码关注云+社区

领取腾讯云代金券