kafka 学习笔记「消息丢失」

147 阅读2分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

本文主要阐述一下在开发过程中可能发生的 kafka 消息丢失问题。

消息丢失

首先问自己,可能丢失的阶段有哪些?

  1. producer 丢失
  2. consumer 丢失
  3. kafka server 丢失

清楚了阶段,就来想想,如何解决丢失?

producer

一般来说,producer 发送msg使用 → producer.send(msg) 。这种情况下,开发者发送消息出去,并不知道 msg 是否发送成功:

  1. 发送是异步的 ⇒ client 端有缓冲区 → RecordBatch
  2. 实际意义上的不知道是不是发送成功

此处可以使用:producer.send(msg, callback)

因为既然异步处理,回调的作用就只是在操作完毕后,做一些确认或者是失败补偿机制啥的。

另外就是:重试机制 ⇒ 可以将 retries 设置为较大的值(一般为3),同时注意重试间隔(退避算法啥的)。因为无效的重试是没有意义的,浪费资源。

consumer

这个阶段的丢失其实是:消费者没有真正消费成功这条 msg。如何评定 consumer 消费成功 msg?

就是向 server 发送 commit offset 的请求,server 认定你已经消费了(不然你提交干嘛,闹着玩呢?),但是 consumer 实际上没有对 msg 做处理或者是消费逻辑失败。

解决方案 :auto.commit = trueauto.commit = false

但是紧接出现的问题是:重复消费,以至于如何保证消费幂等的问题?

先按下不表,后面来说这个大块的问题

server

本质来说,如果说是 server 端出问题,一般是副本复制机制没有做到位。

你在单节点情况下,出现了什么 server 宕机;或者是多节点下,同步没有到位,都会有可能发生消息丢失的情况。

这种情况,通过调参解决。涉及 4 个参数:

  1. acks = all
  2. replication.factor ≥ 3
  3. min.insync.replicas > 1
  4. unclean.leader.election.enable = false

对于 1 :看开发情况,是否需要全部副本都接收到 msg

对于2/3:replication.factor = min.insync.replicas + 1 不能说一个副本挂了,导致整个集群无法正常工作,不符合高可用。

对于 4:当 leader 副本发生故障时就不会从 follower 副本中和 leader 同步程度达不到要求的副本中选择出 leader ,这样降低了消息丢失的可能性。