当前位置:   article > 正文

Kafka如何防止消息丢失?_kafka消费消息过程报错,怎样防止消息丢失

kafka消费消息过程报错,怎样防止消息丢失

1、producer到broker的消息不丢失:ack机制

acks 参数配置:

  • 0: producer 不等待 broker(或者说是leader)的 ack,这一操作提供了一个最低的延迟, broker 一接收到还没有写入磁盘的数据就已经返回,当 broker 故障时有可能丢失数据。可以保证数据不重复,但是不能保证数据不丢失。

  • 1: producer 等待 broker 的 ack, partition 的 leader 落盘成功后返回 ack,如果在 follower同步成功之前 leader 故障,那么将会丢失数据;

  • -1(all) : producer 等待 broker 的 ack, partition 的 leader 和 ISR(同步副本) 里的follower 全部落盘成功后才返回 ack。但是如果在 follower 同步完成后, broker 发送 ack 之前, leader 发生故障,那么会造成数据重复。(假如ISR中没有follower,就变成了 ack=1 的情况)。可以保证数据不丢失,但是不能保证数据不重复。

2、broker到consumer消息不丢失:

consumer 采用 pull(拉) 模式从 broker 中读取数据。consumer会维护一个offset,该offset实时记录着自己消费的位置。同时消费者能见到的最大的 offset,是HW, 是ISR 中最小的 LEO,所以只要保证offset不出错,那消息就不会丢失或者重复消费。但是offset的维护并不是那么简单,它分为好几种方式。

offset的维护方式:

自动提交

enable.auto.commit:是否开启自动提交 offset 功能,消费者只在启动的时候去访问offset的值,如果将该值配置为false,就要手动提交offset,否则offset就不会更新。

auto.commit.interval.ms:自动提交 offset 的时间间隔

手动提交

commitSync(同步提交)

commitAsync(异步提交)

两者的相同点是:都会将本次 poll 的一批数据最高的偏移量提交;

不同点是:commitSync 阻塞当前线程,一直到提交成功,并且会自动失败重试(由不可控因素导致,也会出现提交失败);而 commitAsync 则没有失败重试机制,故有可能提交失败。

无论是同步提交还是异步提交 offset,都有可能会造成数据的漏消费或者重复消费。先提交 offset 后消费,有可能造成数据的漏消费;而先消费后提交 offset,有可能会造成数据的重复消费。

自定义存储offset

offset 的维护是相当繁琐的, 因为需要考虑到很多东西,例如消费者的 Rebalace。

如果开启了自动提交,那消费出现异常时,需要我们去维护一张表,去重新拉取此offset值的消息,重试消费,尝试几次后还是失败的话则此消息置为失败。

为了保证消息不丢失,建议使用手动提交偏移量。避免了拉取消息后,业务逻辑未处理完,自动提交了偏移量,但消费者挂了的情况。

三种语义

At Most Once 语义:

  • 将服务器 ACK 级别设置为 0,可以保证生产者每条消息只会被发送一次,即 At Most Once 语义。

  • 此语义可以保证数据不重复,但是不能保证数据不丢失。

At Least Once 语义:

  • 将服务器的 ACK 级别设置为-1(all),可以保证 Producer 到 Server 之间不会丢失数据,即 At Least Once 语义。

  • 此语义可以保证数据不丢失,但是不能保证数据不重复。

Exactly Once 语义:

  • At Least Once + 幂等性 = Exactly Once

  • 幂等性:所谓的幂等性就是指 Producer 不论向 Server 发送多少次重复数据, Server 端都只会持久化一条。

  • 要启用幂等性,只需要将 Producer 的参数中 enable.idempotence 设置为 true 即可(此时 ack= -1)。 Kafka的幂等性实现其实就是将原来下游需要做的去重放在了数据上游。原理:开启幂等性的 Producer 在初始化的时候会被分配一个 PID,发往同一 Partition 的消息会附带 Sequence Number。而Broker 端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时, Broker 只会持久化一条。

  • 但是 PID 重启就会变化,同时不同的 Partition 也具有不同主键,所以幂等性无法保证跨分区、跨会话的 Exactly Once。(也就是说它只解决单次会话、单个分区里的消息重复问题)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/809442
推荐阅读
相关标签
  

闽ICP备14008679号