KafKa - 分区副本消息同步策略 及 消息丢失问题
Posted 小毕超
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KafKa - 分区副本消息同步策略 及 消息丢失问题相关的知识,希望对你有一定的参考价值。
一、KafKa副本消息同步策略
在开始前需要了解两个概念:LEO
和 HW
:
LEO
: 该副本数据最后一个offset提交的位置,最大offset值。HW
: 高水位线 消费者能够消费最大的offset值。
其中 HW
也叫做复制点,表示副本间同步的位置,如下图所示:
其中 HW
就是消息数最少的那个副本的当前最大的 offset
值为 HW
的值,也是消费者能够消费最大的offset
值。同样在主从复制的时候也是以该值作为分界线向后同步主节点的数据。
对于LEO
,follower
节点只保存自身的,但是leader
节点除了保存自身的,还会保存follower
节点的。
那我们向 kafka 发送一条消息,是怎样进行同步的呢?
就以上图为例,假如我们发送了 4 条消息,offset
值 为 12、13、14、15
-
首先数据消息会被写入
leader
节点,leader
增大自己的LEO
值为 15 此时HW
值还是 11
-
然后
follower
节点发送FETCH
请求,携带自身的LEO
,leader
节点根据根据接受的LEO
更新本地保存的该follower
节点的LEO
值,并取follower
节点中最小的LEO
值来更新自身的HW
值,最后返回follower
LEO
值之后的数据以及自身的HW
值。 -
follower
节点接收到数据后更新自身的LEO
值和leader
节点返回的HW
值。
-
然后
follower
节点再次向leader
节点拉取数据,携带自身的LEO
,leader
节点收到后同样取follower
节点中最小的LEO
值来更新自身的HW
值,返回给follower
节点。
-
如此往复,从而保证数据的一致性。
二、副本故障处理机制 及 消息丢失问题
上面了解到了副本之间数据同步的策略,那假如同步期间某个 follower
节点,或者是 leader
节点因为突发情况退出集群,或有新的节点重新加入集群,数据同步的方式是怎样的呢,会不会发生数据丢失的问题。
假如数据同步如下图的情况:
follower1
节点此时正同步数据,已经同步数据至 offset:13
,但此时由于某些突发因素,导致 follower1
节点宕机,被移除 ISR
列表。而此时follower2
节点正常同步数据,假如此时的 HW
值已经同步到 12 了,然后 follower1
节点又启动起来了那就变成这个下图这种情况:
此时为了保证数据的一致性 follower1
节点会截取高于当前 HW
高水位线后面所有的offset
消息,删除掉,在从该位置开始同步 leader
节点的数据。
如果上面发生宕机的不是follower
节点,而是 leader
节点呢:
此时根据ISR
选举机制,leader
节点被移出 ISR
列表,follower1
节点顺利升级为 leader
节点,数据同步后变成了下图这种情况:
下面原leader
节点又重新启动起来,根据同步策略会截取高于当前 HW
高水位线后面所有的offset
消息进行删除,就变成了下面的情况:
此时应该就会发现问题所在了,消息 offset
值为 14、15的消息都被丢失了,所以 Kafka
实现集群,可以保证每个副本的数据一致性问题,但是不能保证消息不会丢失。
二、预防消息丢失问题
既然kafka 不能保证消息不会丢失,那么可以在业务层面进行插手解决该问题,可以将消息记录在 db 或 noSQL 中,消息被成功消费后,可以更新状态或删除记录,如果某些消息在一定时间后还是没有被消费的情况下,可以视为丢失消息,进行消息的补偿操作。
以上是关于KafKa - 分区副本消息同步策略 及 消息丢失问题的主要内容,如果未能解决你的问题,请参考以下文章