kafka消息一致性
消息丢失的案例:
Leader接收消息后,更新Leader的LEO,但是Remote-LEO和HW并没有更新。

Follower拉取消息,放到本地,此时,更新Follower的LEO为3:

假如,在Follower发起第二次请求的时候,Leader和Follower都宕机,则:

两者随后重启,由于副本重启后以HW作为标准对消息进行截断,则无论哪个先重启,都会对消息进行截断,也就是消息3被丢弃:

消息丢失。
消息保持一致性:
所谓的消息一致性,指的是对于已经同步的消息,Follower应该和Leader消息一样。但是下图的情况就是消息不一致的情况:

发生背景:
Leader接收到消息,更新本地LEO为3:

Follower拉取消息,放到本地,此时,更新Follower的LEO为3:

Follower发起第二次请求,此时,Leader更新Remote-LEO为3,更新HW为3:

Leader回复Follower的时候,Leader和Follower宕机:

假如Follower先重启回来,进行消息截断,变为新的Leader,原来的Leader稍后重启,由于HW是3,因此不进行消息的截断,直接到新Leader拉取偏移量为3的消息。新的Leader开始接收生产者的消息。
此时Follower的{2}消息和Follower的2消息不一样,消息不一致,但是Follower不会从偏移量2开始拉取消息,而是从3拉取消息。

通过在本地记录epoch信息用于截断消息,防止与Leader不一致。
每次发生Leader的变更,控制器要生成新的epoch的值,同时新的Leader记录该键值对:<epoch, beginOffset>
其中beginOffset表示当前Leader从哪条消息开始接管:
| Leader | Follower |
|---|---|
| <0, 0> <1, 10> <2, 25> <3, 50> | <0, 0> |
如:
request({0, 12}):Follower请求纪元为0的时候的偏移量为12的消息。
response(<1, 10>):返回比0大的最小纪元数和纪元对应的offset,意思是follower的纪元0的11,10两条消息多余,删除。
浙公网安备 33010602011771号