kafka消息一致性

本文探讨了分布式系统中消息丢失的案例,以及如何通过记录epoch信息来确保消息一致性。重点介绍了acks配置、LEO更新和Follower的行为,展示了如何通过本地epoch截断避免领导节点重启后的数据不一致问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

消息丢失的案例:

Leader接收消息后,更新Leader的LEO,但是Remote-LEO和HW并没有更新。

如果生产者设置acks=1,则表示此消息已经发送成功。如果acks=-1,默认 min.insync.replics=1,也表示消息已经发送成功:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CbtuwUYT-1630058626214)(consistency.assets/image-20210315112306817.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M9of8hyv-1630058626215)(consistency.assets/image-20210315112435241.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J0FrNq8l-1630058626216)(consistency.assets/image-20210315112509004.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z5PKx8Js-1630058626217)(consistency.assets/image-20210315112636574.png)]

消息丢失。

消息保持一致性:

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B9WUiSAo-1630058626218)(consistency.assets/image-20210315112657091.png)]

发生背景:

Leader接收到消息,更新本地LEO为3:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5aD7RjAG-1630058626218)(consistency.assets/image-20210315112306817.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jMpY6jnF-1630058626219)(consistency.assets/image-20210315112435241.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tIAjyVQf-1630058626219)(consistency.assets/image-20210315113001591.png)]

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3IgfNtp7-1630058626220)(consistency.assets/image-20210315113140913.png)]

假如Follower先重启回来,进行消息截断,变为新的Leader,原来的Leader稍后重启,由于HW是3,因此不进行消息的截断,直接到新Leader拉取偏移量为3的消息。新的Leader开始接收生产者的消息。

此时Follower的{2}消息和Follower的2消息不一样,消息不一致,但是Follower不会从偏移量2开始拉取消息,而是从3拉取消息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tQsYcr51-1630058626220)(consistency.assets/image-20210315115215389.png)]

通过在本地记录epoch信息用于截断消息,防止与Leader不一致。

每次发生Leader的变更,控制器要生成新的epoch的值,同时新的Leader记录该键值对:<epoch, beginOffset>

其中beginOffset表示当前Leader从哪条消息开始接管:

LeaderFollower
<0, 0>
<1, 10>
<2, 25>
❤️, 50>
<0, 0>

如:

request({0, 12}):Follower请求纪元为0的时候的偏移量为12的消息。

response(<1, 10>):返回比0大的最小纪元数和纪元对应的offset,意思是follower的纪元0的11,10两条消息多余,删除

偏移量为12的消息。

response(<1, 10>):返回比0大的最小纪元数和纪元对应的offset,意思是follower的纪元0的11,10两条消息多余,删除

请添加图片描述
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值