【问题标题】:Adding to a Kafka topic exactly once仅一次添加到 Kafka 主题
【发布时间】:2018-10-28 09:11:12
【问题描述】:

从 0.11 开始,Kafka Streams 提供了完全一次的保证,但他们对端到端中“结束”的定义似乎是“一个 Kafka 主题”。

对于实时应用程序,第一个“末端”通常不是 Kafka 主题,而是某种将数据(可能通过多个层和网络)输出到 Kafka 主题的应用程序。

那么,面对网络故障、应用程序崩溃和重新启动,Kafka 是否提供了一些东西来添加到一个主题中?还是我必须使用 Kafka 的 at-least-once 语义,并通过一些唯一标识符将可能重复的主题重复数据删除到另一个完全一次性主题中?

编辑由于大众需求,这里有一个特定的用例。我有一个客户端 C,它创建消息并将它们发送到服务器 S,它使用 KafkaProducer 将这些消息添加到 Kafka 主题 T。

我怎么能保证,面对

  • C、S 和 Kafka 集群成员崩溃
  • 临时网络问题

C 创建的所有消息都在 T 中结束,恰好一次(并且 - 每个分区 - 以正确的顺序)?

我当然会让 C 重新发送它没有从 S 得到确认的所有消息 -> 至少一次。但要做到精确一次,C 发送的消息需要包含某种 ID,以便执行重复数据删除。那,我不知道我怎么能用 Kafka 做到这一点。

【问题讨论】:

  • 使用幂等生产者和事务应该有助于一次将数据写入 Kafka 主题——您仍然需要编写额外的自定义代码以避免重复。这个问题是开放式的,但很难详细回答。
  • 如果您能提供更详尽的细节,我们可以尝试回答这个问题。现在,它太模糊了。
  • @MatthiasJ.Sax 关于最基本的问题 - 从 Kafka 用户的角度来看 - 操作,即“将项目添加到主题”,“开放式”是什么?我怎样才能缩小范围?
  • “Kafka 是否提供了一些可以一次性添加到主题的东西”-> 如上所述:是的,但如果没有自定义代码,它可能不是一个完整的解决方案。研究幂等生产者和交易。不确定您是否熟悉这两种功能 - 如果是,请缩小范围,了解为什么这些功能不能满足您的需求。
  • @MatthiasJ.Sax 我在问题中添加了一个用例 - 希望足够具体。

标签: apache-kafka


【解决方案1】:

Kafka 的一次性功能,尤其是“幂等生产者”可以帮助您解决服务器崩溃和网络问题。

您可以通过 Producer 配置 enable.idempotence=true 启用幂等性,您可以将其作为任何其他配置传入。这样可以确保在服务器崩溃或出现任何网络问题时,每条消息都以正确的顺序写入一次。

Kafka 的exactly-once 功能,如果生产者崩溃,不提供支持。对于这种情况,您需要编写手动代码,以确定在崩溃之前(通过使用消费者)成功地将哪些消息附加到主题,并从中断的地方继续发送。作为替代方案,您仍然可以像您已经提到的那样对消费者端进行重复数据删除。

【讨论】:

    【解决方案2】:

    您可能想看看 kafka 的日志压缩功能。如果您对所有重复消息都有唯一的密钥,它将为您删除重复消息。

    https://kafka.apache.org/documentation/#compaction

    更新:

    日志压缩不是很可靠,但是您可以更改一些设置以按预期工作。

    更有效的方法是使用 kafka 流。您可以使用 KTables 实现此目的。

    【讨论】:

    • 日志压缩是完全不同的东西。它释放了空间,但不会阻止 Kafka 消费者收到两次相同的物品。
    • 没有办法避免......假设重复的记录是在时间 t , t+5min 和 t+10min 产生的.. 我们无法知道记录是重复的在时间 t。此外,压缩不仅仅是为了释放空间,它还可以确保您拥有最新的记录状态。
    猜你喜欢
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 2019-08-13
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    相关资源
    最近更新 更多