11 无消息丢失配置

kafka 什么情况下保证消息不丢失

kafka对已提交的消息做有限度的持久化保证。

什么是已提交的消息
kakfa若干年broker成功收到一条消息并写入日志文件后,会告诉生产者程序这条消息已经成功提交。

什么是有限度
消息保留在N个broker上,至少要有一个存活

“数据丢失”案例

这里的数据丢失不一定是kafka的锅

生产者丢失数据

调用的是 producer.send(msg) 这个 API,那么它会立即返回,不管发送的结果成功与否。原因很多,可能是网络抖动,消息根本没有到broker;可能是消息格式不正确,比如消息太大了broker无法处理。

解决办法是使用producer.send(msg, callback)这个API,对错误做针对性处理。如果是网络抖动会自动重试;如果是消息格式的问题,调整消息格式再发送。

补充
1.为什么将min.insync.replicas设置为大于1保证消息可用性,replication.factor > min.insync.replicas

kafka权威指南里的解释,生产者指定ack=all, 是要求同步副本也就是ISR(min.insync.replicas指定的就是最小同步副本个数),而不是分区的所有副本(replication.factor指定的是副本数目),都接收到消息,才算成功。

replication.refactor是副本replica总数, min.insync.replicas是要求确保至少有多少个replica副本写入后才算是提交成功,这个参数是个硬指标;acks=all是个动态指标,确保当前能正常工作的replica副本都写入后才算是提交成功。举个例子:比如,此时副本总数3,即replication.factor = 3,设置min.insync.replicas=2,acks=all,那如果所有副本都正常工作,消息要都写入三个副本,才算提交成功,此时这个min.insync.replicas=2下限值不起作用。如果其中一个副本因为某些原因挂了,此时acks=all的动态约束就是写入两个副本即可,触达了min.insync.replicas=2这个下限约束。如果三个副本挂了两个,此时ack=all的约束就变成了1个副本,但是因为有min.insync.replicas=2这个下限约束,写入就会不成功。

2.什么是ISR
kafka是由follower周期性或者尝试去pull(拉)过来(其实这个过程与consumer消费过程非常相似)

leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护

由于broker的原因丢数据

所有的broker都挂了。这种情况消息并没有commit,符合开头提出的论点。

消费者丢数据

先更新位移,再消费消息,这种情况可能导致消息丢失。

解决办法是关掉消费者自动提交位移,程序手动提交位移。

还有一种情况是单consumer多线程消费

避免无消费消息丢失很简单,但极易出现消息被消费了多次的情况。

参考https://www.cnblogs.com/huxi2b/p/7089854.html

你可能感兴趣的:(kafka核心技术与实战,kafka)