kafka学习笔记(五) --- 无消息丢失配置怎么做?

kafka在什么情况下才能保证消息不丢失?

首先一句话概括为,kafka只对已提交消息做有限度的持久化保证。

已提交消息:当kafka的若干个broker接收到消息并成功写入日志文件后,他们会告诉生产者程序已成功提交。为什么是若干个broker,就取决于你对“已提交”的定义。可以选择只要有一个broker成功保存消息就算已提交,也可以是所有broker都成功保存该消息就算已提交。

有限度的持久化保证:kafka不丢消息是有前提条件的。假如你的消息保存在N个kafka broker上,那么这个前提条件就是这N个broker中至少有1个存活。

“消息丢失”案例:加引号说明很多时候消息丢失并不是kafka本身造成 的消息丢失。

生产者程序丢失数据:在程序中调用了不带回调参数的send API,这种方式发送出去的消息,不管成功与否,对于发送端都是已成功发送的消息。这种情况下消息丢失的原因很多的,例如网络抖动,导致消息就没有发送到broker端;或者消息本身不合格导致broker端拒收(比如消息太大,超过broker承受能力)。至此,这些个情况,kafka都不认为消息已提交,也就没有消息丢失一说。这种情况的解决方法,producer端永远要调用带有回调通知的send API,即不要使用producer.send(msg),而要使用producer.send(msg, callback)。当然,如果在极端情况下,所有broker宕机,无论producer怎么重试都会失败,这种情况,kafka也依然不认为消息已提交,故不做持久化保证。

消费程序丢失数据:consumer端数据丢失,一般主要体现体现在要消费的消息不见了,这里consumer端有个位移的概念表示的是consumer当前消费到topic分区的位置。一种情况的消息丢失是因为消费顺序和更新位移顺序颠倒,所有要保证先消费再更新位移,但是这种情况可能会导致重复消费消息,这种情况后面在讨论。

另外一种消息丢失场景是:consumer端从kafka获取消息后开启多线程异步处理消息,而consumer端自动向前更新位移。加入其中的线程运行失败了。它负责的消息没有被处理,但位移已经更新了,那么这条消息对于consumer而言就丢失。这种情况就不要开启自动提交位移。但是,单个consumer程序使用多线程处理消息,避免消息丢失很容易,但是极易出现消息消费多次的情况。

还有一种消息丢失的场景,增加主题分区。当增加主题分区后,在某段不凑巧的时间间隔后,producer先于consumer感知到增加的分区,而consumer设置成“从最新位移处”开始读消息,那么在consumer感知到新增分区之前,producer发送的消息就全部“丢失”。

下面分享一个无消息丢失的配置:

1. 不要使用producer.send(msg),而要使用producer.send(msg, callback)。

2. 设置acks = all。acks是producer的参数,代表对已提交消息的定义。如果设置成all,则表明所有副本broker都要接收到消息,才算已提交。

3. 设置retries为一个较大值,也是producer端参数,对应produce端的自动重试。当网络出现抖动,消息发送可能会失败,此时配置retries>0的producer能够自动重试消息发送,避免消息丢失。

4. 设置unclean.leader.election.enable = false,broker端参数,它控制的是那些broker有资格竞选分区leader。如果一个broker落后原先leader太多,那么它一旦成为新leader,必然造成消息丢失。一般情况设置为false。

5. 设置replicator.factor >= 3,broker端参数。这里表述的是最好将消息多保存几份,目前防止消息丢失的主要机制就是冗余。

6. 设置min.insync.replicas > 1,broker端参数。控制的是消息至少要被写入到多少个副本才算已提交。

7. 确保replicator.factor > min.insync.replicas。如果两者相等,那么只要有一个副本挂机,整个分区都无法正常工作。不仅要改善消息持久性,防止丢失,还要在不降低可用性上完成。推荐设置成replicator.factor = min.insync.replicas + 1.

8. 确保消息消费完成再提交,设置enable.auto.commit = false,手动提交位移。

标注:这个系列文章是本人在极客时间专栏---kafka核心技术与实战中的学习笔记

    https://time.geekbang.org/column/article/101171

发布了37 篇原创文章 · 获赞 20 · 访问量 4960

猜你喜欢

转载自blog.csdn.net/qq_24436765/article/details/101706580