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

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

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

  • 数据丢失
  • 数据不一致

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

数据丢失

下图是一张关于数据丢失的状态图,下面讲述一下到底发生了什么导致了数据的丢失。
Kafka基于HW备份恢复弊端分析(III)_第1张图片

从图中,我们可以看出初始状态,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到底发生了哪些变化。
Kafka基于HW备份恢复弊端分析(III)_第2张图片

初始状态为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首次写底层日志时,会在缓存中增加一个条目,否则不做更新。

Kafka基于HW备份恢复弊端分析(III)_第3张图片

Kafka基于HW备份恢复弊端分析(III)_第4张图片

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

你可能感兴趣的:(kafka,java)