kafka之消息场景丢失配置

1.kafka只对已提交的消息做有限度的持久化保证。
已提交的消息:当kafka的若干个Broker成功地接收一条消息并写入到日志文件后,会告诉生产者程序这条消息已提交成功。有限度的持久化保证:假如你的消息保存在N个kafka Broker,至少有一个Broker是存活的。
2.消息可能丢失的场景
消息可能丢失的场景:

  • 生产者发送消息到broker,但broker未落地到磁盘或未同步到follower
  • 生产者异步发送,消息仍处于内存中,进程奔溃
  • 消费者手动提交offset,但后续处理失败

解决方法:

  • topic设置分区数以及副本数,producer发送消息时需要指定acks=all,即leader存储成功之后,follower也需要存储成功。
  • 设置同步发送,设置linger.ms=0 或对send方法返回的Future做get(),等待结果
  • 后置提交,避免提前commit完,进程奔溃或业务处理失败丢消息的场景。
  • ucff默认配置:SdkConfigurationReset.properties

消息成功投递的保证:

  • 最多一次:消息最多投递一次,消息可能丢失,但肯定不会重复。
  • 最少一次:消息最少投递一次,消息可能丢失,但可能会重复。
  • 有且仅有一次:消息只会被传递一次,不丢失也不重复。

2.1 生产者程序丢失数据
producer程序丢失消息,目前是异步发送消息,即调用producer.send(msg)这个API,通常会立即返回。所以一般要使用producer.send(msg,callback),带有回调通知的发送API,会通知你的消息是否真的提交成功了。可能丢失的原因:

  • 1、网络抖动,导致消息压根没有发送到Broker端
  • 2、消息本身不合格导致Broker拒绝接收(比如消息太多,超过Broker的承受能力)
  • 3、Broker端宕机

2.2 消费者程序丢失数据
维持先消费消息,在更新位移的顺序。
位移:书签。

3.kafka无消息丢失的配置

  • 1.不要使用 producer.send(msg),而要使用 producer.send(msg, callback)。
  • 记住,一定要使用带有回调通知的 send 方法。
  • 2.设置 acks = all。
  • acks 是 Producer 的一个参数,代表了你对“已提交”消息的定义。如果设置成 all,则表明所有副本 Broker 都要接收到消息,该消息才算是“已提交”。这是最高等级的“已提交”定义。
  • 3.设置 retries 为一个较大的值。
  • 这里的 retries 同样是 Producer 的参数,对应前面提到的 Producer 自动重试。当出现网络的瞬时抖动时,消息发送可能会失败,此时配置了 retries > 0 的 Producer 能够自动重试消息发送,避免消息丢失。
  • 4.设置 unclean.leader.election.enable = false。
  • 这是 Broker 端的参数,它控制的是哪些 Broker 有资格竞选分区的 Leader。如果一个 Broker 落后原先的 Leader 太多,那么它一旦成为新的 Leader,必然会造成消息的丢失。故一般都要将该参数设置成 false,即不允许这种情况的发生。
  • 5.设置 replication.factor >= 3。这也是 Broker 端的参数。其实这里想表述的是,最好将消息多保存几份,毕竟目前防止消息丢失的主要机制就是冗余。
  • 6.设置 min.insync.replicas > 1。这依然是 Broker 端参数,控制的是消息至少要被写入到多少个副本才算是“已提交”。设置成大于 1 可以提升消息持久性。在实际环境中千万不要使用默认值 1。- - 7.确保 replication.factor > min.insync.replicas。如果两者相等,那么只要有一个副本挂机,整个分区就无法正常工作了。我们不仅要改善消息的持久性,防止数据丢失,还要在不降低可用性的基础上完成。
  • 8.推荐设置成 replication.factor = min.insync.replicas + 1。确保消息消费完成再提交。Consumer 端有个参数 enable.auto.commit,最好把它设置成 false,并采用手动提交位移的方式。就像前面说的,这对于单 Consumer 多线程处理的场景而言是至关重要的。

总结:

总结:以上是保证消息不被丢失的配置。

 

posted @ 2022-03-12 17:18  郭慕荣  阅读(123)  评论(0编辑  收藏  举报