陪你一起学kafka(四)——消息不丢失

292 阅读3分钟

前言

随着微服务的发展,kafka消息中间件作为异步解耦,流量削峰的重要手段已经必不可少。同时如何保证消息不丢失也成为了必须要解决的问题。下面七个建议将帮你解决。

建议

消息生产者发送消息的时候设置回调函数

设置回调函数,其实就是消息确认机制,有以下作用:

  • 监听消息是否成功到达broker
  • 记录消息日志到mongo,便于定位问题
  • 可以适当做一些消息补偿机制,比如对失败的消息进行重发

image.png

设置acks参数

acks是Producer的一个参数,代表“已提交”消息的定义。可以设置的值有all,0,1,-1。可以结合实际业务进行设置

#procedure要求leader在考虑完成请求之前收到的确认数,用于控制发送记录在服务端的持久化,其值可以为如下:
#acks = 0 如果设置为零,则生产者将不会等待来自服务器的任何确认,该记录将立即添加到套接字缓冲区并视为已发送。在这种情况下,无法保证服务器已收到记录,并且重试配置将不会生效(因为客户端通常不会知道任何故障),为每条记录返回的偏移量始终设置为-1。
#acks = 1 这意味着leader会将记录写入其本地日志,但无需等待所有副本服务器的完全确认即可做出回应,在这种情况下,如果leader在确认记录后立即失败,但在将数据复制到所有的副本服务器之前,则记录将会丢失。
#acks = all 这意味着leader将等待完整的同步副本集以确认记录,这保证了只要至少一个同步副本服务器仍然存活,记录就不会丢失,这是最强有力的保证,这相当于acks = -1的设置。
spring.kafka.producer.acks=all

设置retries参数

建议设置为一个较大的值。同样是Producer的参数。当出现网络抖动时,消息发送可能会失败,此时配置了retries的Producer能够自动重试发送消息,尽量避免消息丢失。

spring.kafka.producer.retries=3

设置unclean.leader.election.enable = false。

这是Broker端的参数,在kafka版本迭代中社区也多次反复修改过他的默认值,之前比较具有争议。它控制哪些Broker有资格竞选分区的Leader。如果一个Broker落后原先的Leader太多,那么它一旦成为新的Leader,将会导致消息丢失。故一般都要将该参数设置成false。

unclean.leader.election.enable = false

设置replication.factor >= 3。

这也是Broker端的参数。保存多份消息冗余,不多解释了。

replication.factor >= 3

设置min.insync.replicas > 1。

Broker端参数,控制消息至少要被写入到多少个副本才算是“已提交”。设置成大于 1 可以提升消息持久性。在生产环境中不要使用默认值 1。确保replication.factor > min.insync.replicas。如果两者相等,那么只要有一个副本离线,整个分区就无法正常工作了。推荐设置成replication.factor = min.insync.replicas + 1。

确保消息消费完成再提交。

Consumer端有个参数enable.auto.commit,最好设置成false,并自己来处理offset的提交更新。

image.png