跳转至

Kafka 消费语义

At-Least-Once

生产者侧

依赖于 Kafka 自身机制

可以通过设置 retries 参数以及 delivery.timeout.ms (一条消息成功发送的最长容忍时间,包括重试时间,需要合理配置来容纳配置的 retries 次数)。

这些自身的机制适合处理暂时性的可恢复故障,例如:

  • 网络抖动
  • broker 短暂超负荷
  • leader replica 选举 / ISR 数量低于 min.insync.replicas

依赖于业务逻辑 / 封装

使用 SyncProducer,在业务层实现对于发送失败消息的立刻手动重试

此时可以关注 ack 的设置

消费者侧

如果对于消息的漏消费容忍度低,主要通过设置 enable.auto.commit 参数为 false,由业务层来手动提交偏移量,决定消费是否成功。

具体可见 Kafka 确认机制 - 消费者端实现重试与确认机制

Idempotence

在 at least once 的基础上实现幂等性

生产者侧

生产者重发,导致 broker 重复持久化的情况,Kafka 从机制上会去避免

当 Kafka 生产者向 broker 发送消息时,可能会因为网络抖动等原因造成消(网络包)的重复发送

当生产者设置了重试次数,发生网络抖动后,producer 客户端自动重发请求,导致 broker 侧重复收到消息

此时,可以在生产者侧启动幂等性配置(默认为开启):

enable.idempotence=true

由于每个生产者有一个唯一标识 producerID,以及一个 SeqNumber 作为发送的消息的自增序列号

broker 会丢弃来自相同 producerID,且 SeqNumber 小于或等于已经记录的 SeqNumber 的消息

消费者侧

导致消费者侧重复消费的可能原因为:

  • 消费者完成了消息的处理,但是没有提交 offset 就崩溃了
  • 消费者组发生了 rebalance

消费者侧一般在业务层去防止消息的重复消费,可以为每条消息设置一个 UUID,基于公共数据中心(如 redis / mysql)来防止重复。