KAFKA消息丢失

KAFKA默认配置,既可能丢失消息,也可能重复消费消息。默认配置以高吞吐量为目的。
kafka在生产端 、消费端、BROKER 时都可能会丢失一些消息
7.1 生产者端配置消息丢失
生产者在发送消息时,会有一个ack机制,当ack=0 或者 ack=1时,都可能会丢消息。Kafka默认ack=1。说明如下所示:

  1. acks=0表示producer不需要等待任何broker确认收到消息的回复,就可以继续发送下一条消息。性能最高,但是最容易丢消息。对数据丢失不敏感的情况可以用这种。
  2. acks=1至少要等待leader已经成功将数据写入本地log,但是不需要等待所有follower是否成功写入。就可以继续发送下一条消息。这种情况下,如果follower没有成功备份数据,而此时leader又挂掉,则消息会丢失。
  3. acks=-1或all这意味着leader需要等待所有备份(配合min.insync.replicas(最少同步副本数)使用)都成功写入日志,这种策略会保证只要有一个备份存活就不会丢失数据。这是最强的数据保证。一般除非是金融级别,或跟钱打交道的场景才会使用这种配置。当然如果min.insync.replicas配置的是1则也可能丢消息,跟acks=1情况类似。
  4. retries,客户端发送失败,重试次数(默认:2147483647,即Integer.MAX_VALUE)。如果设置为0,只要发送消息失败,这笔消息就丢失了

解决办法:acks设置all; min.insync.replicas 设置为副本数;retries默认配置。
另外可以在send函数对应的回调函数Callback逻辑中,加入丢失补偿处理机制。譬如发短信告诉运维人员。
7.2 broker端配置消息丢失

  1. unclean.leader.election.enable 配置true broker端配置
    允许选举ISR以外的副本作为leader,会导致数据丢失,默认为false。producer发送异步消息完,只等待lead写入成功就返回了,leader crash了,这时ISR中没有follower,leader从OSR中选举,因为OSR中本来落后于Leader造成消息丢失。

解决办法:

  1. unclean.leader.election.enable设置false。禁止OSR中产生leader;
    关闭unclean选举,不允许非ISR的副本被选举为Leader,从而避免broker端因日志水位截断造成的消息丢失
  2. replication.factor >=3
    参考了Hadoop以及业界的三备份原则
  3. min.insync.replicas > 1
    用于控制某条消息至少被写入ISR中多少个副本才算成功。设置大于1
    确保replication.factor > min.insync.replicas
    若两者相等,那么只要一个副本挂掉,分区就无法工作。推荐replication.factor = min.insync.replicas + 1

7.3 消费端消息丢失

  1. 消费端丢消息最主要体现在消费端offset的自动提交,如果开启了自动提交,万一消费到数据还没处理完,此时你consumer直接宕机了,未处理完的数据 丢失了,下次也消费不到了,因为offset已经提交完毕,下次会从offset出开始消费新消息。
  2. 解决办法是采用消费端的手动提交
    //手动提交offset
    /**

    • 注意如果要使用手动提交offset,需要以下三点
    • ①:配置文件配置手动提交方式
    • ②:加上参数Acknowledgment ack kafka的spring版本
    • ③:方法中使用ack.acknowledge();手动提交
      */

    consumer.commitSync(); // 直接使用kafka-client版本

作者:zzzZY5Vi原文地址:https://segmentfault.com/a/1190000041592099

%s 个评论

要回复文章请先登录注册