【kafka实践】06|如何避免保证消息丢失

消息丢失问题在所有消息中间价都是一个大问题,那么kafka是如何保证消息不丢失的呢?

目录

责任边界

消息丢失案例

生产者丢失

消费者丢失

最佳实践


责任边界

可以概括为:Kafka 只对“已提交”的消息(committed message)做有限度的持久化保证。

什么是已提交的消息?当 Kafka 的若干个 Broker 成功地接收到一条消息并写入到日志文件后,它们会告诉生产者程序这条消息已成功提交。此时,这条消息在 Kafka 看来就正式变为“已提交”消息了。为什么是若干个 Broker 呢?着取决于Broker端的配置。

有限度就是说 Kafka 不可能保证在任何情况下都做到不丢失消息。比如机房断电、机房火灾等极端情况。

消息丢失案例
生产者丢失

Producer 程序丢失消息,这应该算是被抱怨最多的数据丢失场景了。比如这个场景:你写了一个 Producer 应用向 Kafka 发送消息,最后发现 Kafka 没有保存,然后客户端又没有相关日志报错,让你无从下手。

我们来分析下可能的原因,Kafka Producer 是异步发送消息的,当你调用producer.send(msg) ,它会立即返回,但此时你不能认为消息发送已成功完成。这种发送方式有个有趣的名字,叫“fire and forget”,简单翻译就是“发后即忘”。用该方式当发生网络抖动,消息格式错误等问题时不能及时发现,那我们不能甩锅给kafka。事实上我们应该使用带回调的发送方式producer.send(msg, callback),通过回调我们才能真正确定是否发送成功,或是出了什么问题。

消费者丢失

Consumer 程序有个“位移”的概念,表示的是这个 Consumer 当前消费到的 Topic 分区的位置。

这里的“位移”类似于我们看书时使用的书签,它会标记我们当前阅读了多少页,下次翻书的时候我们能直接跳到书签页继续阅读。假如你读到第50页,但是却不小心将书签放在60页,那就丢了中间10页内容。同理,Kafka 中 Consumer 端的消息丢失也如此。要处理这种消息丢失,办法很简单:维持先消费消息(阅读),再更新位移(书签)的顺序即可。这样就能最大限度地保证消息不丢失

最佳实践

根据以上内容,可以得出一下最佳实践:

  • 不要使用 producer.send(msg),而要使用 producer.send(msg, callback)。记住,一定要使用带有回调通知的 send 方法。
  • acks = all。acks 是 Producer 的一个参数,代表了你对“已提交”消息的定义。如果设置成 all,则表明所有ISR副本 Broker 都要接收到消息,该消息才算是“已提交”。
  • retries 为一个较大的值。这里的 retries 同样是 Producer 的参数。当出现网络的瞬时抖动时,如果配置了 retries > 0 的 Producer 能够自动重试消息发送。
  • replication.factor >= 3。 Broker 端的参数,将消息多保存几份,毕竟目前防止消息丢失的主要机制就是冗余。
  •  min.insync.replicas(ISR) > 1。 Broker 端参数,控制的是消息至少要被写入到多少个副本才算是“已提交”。设置成大于 1 可以提升消息持久性。在实际环境中千万不要使用默认值 1。
  • 确保 replication.factor > min.insync.replicas。如果两者相等,那么只要有一个副本挂机,整个分区就无法正常工作了。推荐设置成 replication.factor = min.insync.replicas + 1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值