文章目录
- 已提交与有限度
- 生产者丢失数据
- 异步发送消息
- 解决方式
- 消费者丢失数据
- 更新offset时机
- 设置手动提交
- 最佳实践
已提交与有限度
Kafka对已提交的消息做有限度的持久化保证。
- 已提交消息:Kafka的若干个Broker成功接收到消息并写入日志文件后,告诉生产者已成功提交。已提交的定义如下
- 一个Broker成功保存消息为已提交
- 所有Broker都成功保存消息为已提交
- 有限度的持久化保证:有限度的意思是假如有N个Broker,要想保证持久化,就至少有一个存活。
生产者丢失数据
异步发送消息
当异步发送消息的时候,会立即返回,但是不能认为消息发送成功,这个操作代表的意思是发送后不管。出现丢消息的原因如下:
- 网络抖动,消息没有发送到Broker端
- 消息不合格,被Broker拒绝接受
解决方式
Producer 永远要使用带有回调通知的发送 API,也就是说不要使用 producer.send(msg),而要使用 producer.send(msg, callback)。
当出现消息失败的情况,针对性的做相应处理即可
消费者丢失数据
Consumer 端丢失数据主要体现在 Consumer 端要消费的消息不见了
ConsumerA 当前位移值是9,ConsumerB当前位移值是11
更新offset时机
通过消费消息、然后再更新位移,这样能最大限度的保证消息不丢失,但是有可能带来消息重复消费的问题
设置手动提交
Consumer不要开启自动提交位移,通过应用程序手动提交位移
最佳实践
- 使用带有回调通知的send方法producer.send(msg, callback)。
- 设置 acks = all,代表所有的副本Broker都要收到消息才算是已提交,最高级别的已提交定义
- 设置retries为一个较大的值。自动重试消息,避免是吧
- Broker参数unclean.leader.election.enable = false。控制哪些Broker有资格竞选分区的Leader。
- Broker参数 replication.factor>=3,将消息保存多份,通过冗余来方式丢失
- Broker参数 min.insync.replicas > 1,控制消息至少要被写入多个副本才算是已提交。
- replication.factor > min.insync.replicas,两者相等,那么只要有一个副本挂机,整个分区就无法正常工作了,推荐设置为replication.factor = min.insync.replicas + 1。
- 确保消息消费完再提交。Consumer端有个参数enable.auto.commit,最好把它设置成 false,并采用手动提交位移的方式。