kafka如何保证消息不丢失不被重复消费

kafka如何保证消息不丢失不被重复消费

在解决这个问题之前,我们首先梳理一下kafka消息的发送和消费机制。

消息的发送机制

kafka的消息发送机制分为同步和异步机制。可以通过producer.type属性进行配置。使用同步模式的时候,有三种状态来保证消息的安全生产。可以通过配置request.required.acks属性。三个属性分别如下

  • 0—表示不进行消息接收是否成功的确认;
  • 1—表示当Leader接收成功时确认;
  • -1—表示Leader和Follower都接收成功时确认;

当acks = 0的时候,不和Kafka集群进行消息接收确认,则当网络异常、缓冲区满了等情况时,消息可能丢失;当acks=1的时候,只保证leader写入成功。当leader partition挂了的时候,数据就有可能发生丢失。另外还有一种情况,使用异步模式的时候,当缓冲区满了,acks=0的时候,不需要进行消息接受是否成功的确认,所以会自动清空缓冲池里的消息。

同步模式下只需要将确认机制设置为-1,让消息写入leader和所有的副本,就可以保证消息安全生产。

异步模式下,则需要在配置文件中,将阻塞超时的时间设置为不限制。这样生产端会一直阻塞。可以保证数据不丢失。

我们需要设置block.on.buffer.full = true。 这样producer将一直等待缓冲区直至其变为可用。缓冲区满了就阻塞

acks=all。所有的follwoer都响应了消息就认为消息提交成功。

retries=MAX。无限重试。

max.in.flight.requests.per.connnection = 1限制客户端在单个连接上能够发送的未响应的请求的个数。设置为1表示kafka broker在响应请求之前client不能再向broker发送请求了。通过此举可以保证消息的顺序性。

消息的接受机制

消息的接受端保证消息不丢失的情形就比较简单了。kafka的consumer模式是自动提交位移的。我们只需要在代码逻辑中保证位移提交前消息被处理就行。我们可以关闭自动提交位移,设置enable.auto.commit为false。自己手动处理消息后提交位移。

消息的重复消费如何解决

重复消费的问题,一方面需要消息中间件来进行保证。另一方面需要自己的处理逻辑来保证消息的幂等性。极有可能代码消费了消息,但服务器突然宕机,未来得及提交offset。所以我们可以在代码保证消息消费的幂等性。至于方法可以通过redis的原子性来保证,也可以通过数据库的唯一id来保证。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章