Kafka从主题删除记录,而不使用偏移量,而是通过记录的字段

时间:2019-05-17 16:21:09

标签: java apache-kafka spring-kafka

假设我有一个名为“批处理”的主题,具有1个分区,并且我向其发布了数百万条记录以进行处理。我有一个由3个人组成的消费群体来处理这些数百万条记录。我遇到一种情况,即我不再需要处理满足诸如age < 50

这样的特定条件的某些消息子集

如何以编程方式从主题中删除这些消息。就像我在用户界面中单击“取消”按钮一样,它应从age < 50主题中删除那些记录子集,以便消费者不会对其进行处理。

我知道我可以通过运行带有偏移量的命令行来删除消息:-https://github.com/apache/kafka/blob/trunk/bin/kafka-delete-records.sh

还有Java API,但也有偏移:

https://kafka.apache.org/11/javadoc/org/apache/kafka/clients/admin/AdminClient.html#deleteRecords-java.util.Map-org.apache.kafka.clients.admin.DeleteRecordsOptions-

Delete records whose offset is smaller than the given offset of the corresponding partition

但是对于我来说,我不能使用偏移量,因为我只需要删除某些记录,而无需删除all records smaller than the given offset

2 个答案:

答案 0 :(得分:3)

我需要指出的主要事情是,您不应该将Kafka中的数据与数据库中的数据视为同一事物。 Kafka的工作方式并非如此(例如,当我单击X按钮时,Y记录将被删除)。

相反,您应该将主题视为永无止境的数据流。消费者会独立使用 消耗和处理针对Kafka主题生成的每条记录。

将主题视为流可为您提供不同的解决方案:

您可以使用第二个主题,其中包含过滤的结果!

Streaming Diagram
                            ___ Topic A ____
--  Produced Messages -->  |                |      _______________________
                           |________________| --> |                       |
                                                  | Filtering Application |
                            ___  Topic B ___      |                       |
                           |                | <-- |_______________________|
<-- Consumed Messages --   |________________|

解释很简单,您向主题A生成了消息。然后使用Filtering Application,它将:

  1. 消费来自主题A的消息
  2. 基于某些业务逻辑(例如:age < 50)将进行过滤
  3. 将过滤后的消息发送到主题B

最后,您的消费者将收到来自主题B的消息。

现在,在创建过滤应用程序时,您有两个选择:

  1. 使用消费者和生产者实施基本解决方案
  2. 使用Kafka Streams
  3. 使用KSQL

答案 1 :(得分:2)

您不能,Kafka并非旨在像数据库一样使用,它实际上是一个不变的提交日志。删除记录工具主要用于管理任务。

有一个例外,那就是如果您使用log compaction。如果主题紧凑,则可以通过将记录发布到值为NULL的主题来删除键的值。压缩主题通常​​像数据库提交日志一样使用,您可以将它们读入某些下游服务中,在该服务中它像表一样出现。 NULL值应解析为记录删除。

因此,在您的用例中,您将使主题具体化到针对SELECT key FROM TABLE WHERE age > 50;之类的查询进行优化的系统,然后将每个值为NULL的键的记录发布回Kafka主题。您甚至可以在主题的开头开始您的使用者,并记下哪些记录具有age > 50并执行相同的操作,但是效率不高。