Kafka是如何保证数据可靠性和一致性?


什么是可靠性
对于消息系统来说 。所谓可靠性就是指消息可以从生产者(producer)准确的送达到消费者(consumer) 。可靠性保证有三个层次:
At most once 最多一次 。消息可能会丢失 。但是决不重复 。
At least once 至少一次 。消息决不丢失 。但可能会重复 。
Exactly once 恰好一次 。这是最完美的 。既不丢失 。也不重复 。
如果要可靠的准确的传达消息 。需要生产者程序 。消息系统和消费者程序相互合作 。
什么是一致性
对于消息系统来说 。一致性是指 。如果一个消费者c1读到消息m1的offset是x 。那么之后的任何消费者读到的offset是x的消息一定也是c1 。
可以参看我的一个视频《分布式系统中的强一致性和弱一致性》

Kafka是如何保证数据可靠性和一致性?

文章插图
Kafka如何保证可靠性和一致性
如果要可靠的准确的传达消息 。需要生产者程序 。消息系统和消费者程序相互合作 。
Kafka是如何保证数据可靠性和一致性?

文章插图
生产者程序 Producer
生产者需要确认消息成功送达kafka的服务区broker 。并且得到broker的返回消息 。确认消息已经提交(commit) 。如果没有成功返回需要重发 。直到发送成功 。
详细的配置解释 。可以参考我的头条文章《Kafka的可靠性保证 - 生产者的配置》
Kafka服务器集群 Cluster
Kafka的服务器是一个集群 。集群中至少需要包含3个以上的节点 。通过主从备份可以保证不丢消息 。只要提交的消息就保证不丢 。
详细的配置解释 。可以参考我的头条文章《Kafka的一致性保证》
消费者程序 Consumer
消费者从Kafka读取消息以后要妥善处理 。所谓妥善处理 。就是完成自己获取这一条消息的目标 。比如生成一条业务数据存入数据库 。或者发送消息到其他的系统 。
消费者需要准确的维护offset 。也就是消费到哪一条消息了 。如果维护不好 。就会导致丢消息或者重复消费 。可以参考我的头条动画视频《[动画] 如何设计可靠的Kafka的消费者程序 - exactly once》 。
详细的配置解释 。可以参考我的头条文章《Kafka的可靠性保证 - 消费者的配置》
本人 。@小马过河Vizit 。专注于分布式系统原理和实践分享 。希望利用动画生动而又准确的演示抽象的原理 。欢迎关注 。
关于我的名字 。小马过河Vizit 。意为凡事像小马过河一样 。需要自己亲自尝试 。探索才能获得乐趣和新知 。Vizit是指Visualize it的缩写 。一图胜千言 。希望可以利用动画来可视化一些抽象的原理 。
其他观点:
1.Partition Recovery机制
每个Partition会在磁盘记录一个RecoveryPoint, 记录已经flush到磁盘的最大offset 。当broker fail 重启时,会进行loadLogs 。首先会读取该Partition的RecoveryPoint,找到包含RecoveryPoint的segment及以后的segment, 这些segment就是可能没有 完全flush到磁盘segments 。然后调用segment的recover,重新读取各个segment的msg,并重建索引 。
优点
* 以segment为单位管理Partition数据,方便数据生命周期的管理,删除过期数据简单
* 在程序崩溃重启时,加快recovery速度,只需恢复未完全flush到磁盘的segment
* 通过index中offset与物理偏移映射,用二分查找能快速定位msg,并且通过分多个Segment,每个index文件很小,查找速度更快 。
2.Partition Replica同步机制
* Partition的多个replica中一个为Leader,其余为follower
* Producer只与Leader交互,把数据写入到Leader中
* Followers从Leader中拉取数据进行数据同步
* Consumer只从Leader拉取数据
ISR:所有不落后的replica集合, 不落后有两层含义:距离上次FetchRequest的时间不大于某一个值或落后的消息数不大于某一个值, Leader失败后会从ISR中选取一个Follower做Leader 。
3.数据可靠性保证
当Producer向Leader发送数据时,可以通过acks参数设置数据可靠性的级别
【Kafka是如何保证数据可靠性和一致性?】*0: 不论写入是否成功,server不需要给Producer发送Response,如果发生异常,server会终止连接,触发Producer更新meta数据;
*1: Leader写入成功后即发送Response,此种情况如果Leader fail,会丢失数据
*-1: 等待所有ISR接收到消息后再给Producer发送Response,这是最强保证
仅设置acks=-1也不能保证数据不丢失,当Isr列表中只有Leader时,同样有可能造成数据丢失 。要保证数据不丢除了设置acks=-1, 还要保 证ISR的大小大于等于2,具体参数设置:
4.数据一致性保证

推荐阅读