原理剖析:一文搞懂 Kafka Producer(下)

编辑导读:本篇是 Kafka Producer 原理剖析的下篇,对 Kafka Producer的幂等性、实现细节和常见问题进行了详细的解读。AutoMQ 是与 Apache Kafka 100% 完全兼容的新一代 Kafka,可以帮助用户降低90%以上的Kafka成本并且进行极速地自动弹性。作为 Kafka 生态的忠实拥护者,我们也会持续致力于传播 Kafka 技术,欢迎关注我们。

引言

在之前的文章《原理剖析:一文搞懂 Kafka Producer(上)》中,我们介绍了介绍 Kafka Producer 的使用方法与实现原理。这篇将继续介绍 Kafka Producer 的实现细节与常见问题。

幂等性

在一个分布式的消息系统中,各个角色均有可能发生故障。以 Apache Kafka 为例,Broker 和 Client 都有可能会崩溃,Broker 与 Client 之间的网络请求与响应都有可能丢失。根据 Producer 处理这类故障时采取的策略,可以分为以下几种语义:

  • 至少一次(At Least Once):当发生请求超时或者服务端错误时,Producer 重复尝试发送消息直至成功。这样做可以保证每条消息都被写入 Topic,但是可能会发生重复。

  • 至多一次(At Most Once):在超时或报错时 Producer 不进行重试,每条消息仅发送一次。这样做可以避免消息重复,但也可能会导致消息丢失。

  • 精确一次(Exactly Once):Producer 进行适当的重试,以确保每条消息会且仅会被写入 Topic 一次,既不重复,也不遗漏。Exactly Once 的语义是最理想的实现,它可以满足绝大多数业务场景的需求;但同时也是最难以实现的,它需要 Client 与 Broker 之间的密切配合。

Apache Kafka Producer 提供了两个级别的 Exactly Once 的语义实现:

  • 幂等性(Idempotence):确保 Producer 在向某个 Partition 发送消息时,该消息会且仅会被持久化一次。

  • 事务性(Transaction):当 Producer 同时向多个 Partition 发送消息时,确保这些消息要么都被持久化,要么都不被持久化。

这里我们主要介绍 Kafka Producer 幂等性的使用与实现,关于事务消息的实现原理可以参阅我们之前的文章《原理剖析| Kafka Exactly Once 语义实现原理:幂等性与事务消息》。

开启幂等性

Kafka Producer 开启幂等性是非常简单的,它只需要设置几个配置项,而无需修改任何其他代码(Producer 的接口并没有变化)。

相关配置项有:

  • acks

    当指定数量的副本收到消息后,Producer 才会认为消息写入完成。默认为 “all”

    • acks=0

      Producer 不会等待任何 broker 的响应,消息写入网络层后即认为写入成功

    • acks=1

      Producer 会等待 leader broker 的响应

    • acks=all

      Producer 会等待所有同步的(in sync)副本的响应

  • enable.idempotence

    开启幂等性,即,保证每条消息写入且仅被写入一次,同时保证消息按照发送顺序写入。默认为 “true”

    开启此配置时,需要保证 max.in.flight.requests.per.connection 不大于 5,retries 大于 0,acks 设置为 “all”

在使用时需要注意,幂等 Producer 仅能避免由 Producer 内部的重试策略(Producer、Broker 或网络出错)导致的消息重复,它无法处理以下几种情况:

  • 幂等 Producer 仅保证 Session 级别的不重不漏,当 Producer 发生重启时,不能保证重启后与重启前发送的消息不重复。

  • 幂等 Producer 仅保证 Partition 级别的不重不漏,不能保证向多个 Partition 发送的消息不重复。

  • 当 Producer 出于各种原因发送超时时,即,发送耗时超过了 delivery.timeout.ms,Producer 会抛出 TimeoutException;此时无法保证对应的消息是否已经被 Broker 持久化,需要由上层根据情况进行处理。

实现原理

为了实现幂等性,Kafka 引入了以下两个概念:

  • Producer ID(以下简称 PID):Producer 的唯一标识。PID 由 Idempotent Producer 在首次发送消息前,请求 Broker 分配获得,是全局唯一的。PID 仅在 Producer 和 Broker 内部使用,不会暴露给 Client 使用者。

  • Sequence Number(以下简称 SEQ):消息的序列号。该序列号在 (PID, Partition) 维度上严格递增。事实上,SEQ 会存储在 Record Batch 的头中,作为 Batch 中第一条消息的 SEQ,Batch 中其它消息的 SEQ 依次递增。

值得一提的是,PID 与 SEQ 均会跟随消息持久化到 Log 中。

事实上,除了前述两个属性外,还有 Producer Epoch,它与 PID 结合才会唯一标识一个 Producer。它的在不同的场景下有不同的用途:

  • 对于开启事务能力的 Producer(配置了 “transactional.id”),Producer Epoch 同样由 Broker 分配。这样做可以保证,多个具有相同 Transactional ID 的 Producer 中仅会有一个生效,即 “Fence Producer”。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值