Apache kafka 仅阅读卡夫卡主题中的特定消息

Apache kafka 仅阅读卡夫卡主题中的特定消息,apache-kafka,kafka-consumer-api,kafka-python,Apache Kafka,Kafka Consumer Api,Kafka Python,情景: 我正在将数据JSON对象数据写入kafka主题,同时读取我只想根据消息中的值读取一组特定的消息。我正在使用kafka python库 示例消息: {flow_status: "completed", value: 1, active: yes} {flow_status:"failure",value 2, active:yes} 在这里,我只想阅读flow_状态为completed的邮件。您可以创建两个不同的主题;一个用于完成,另一个用于故障状态。然后从已完成的主题中读取消息以进行处

情景:

我正在将数据JSON对象数据写入kafka主题,同时读取我只想根据消息中的值读取一组特定的消息。我正在使用kafka python库

示例消息:

{flow_status: "completed", value: 1, active: yes}
{flow_status:"failure",value 2, active:yes}

在这里,我只想阅读flow_状态为completed的邮件。

您可以创建两个不同的主题;一个用于完成,另一个用于故障状态。然后从已完成的主题中读取消息以进行处理


否则,如果你想把它们放在一个主题中,只想阅读完整的主题,我相信你需要全部阅读它们,并使用简单的if-else条件忽略失败的主题。

在卡夫卡中,这样做是不可能的。 消费者从最新提交的偏移量开始(或从开始,或在特定偏移量处查找),一个接一个地消费消息。 根据您的用例,您的场景中可能会有不同的流程:执行流程的消息进入一个主题,然后是处理操作的应用程序,然后将结果(完成或失败)写入两个不同的主题:通过这种方式,您完成了与失败分开的操作。
另一种方法是使用Kafka Streams应用程序进行过滤,但考虑到它只是一种糖,实际上,Streams应用程序将始终读取所有消息,但允许您轻松过滤消息。

Kafka消费者事先不支持此类功能。您必须按顺序使用所有事件,过滤掉状态已完成的事件并将其放在某个位置。相反,您可以考虑使用卡夫卡流应用程序,其中可以读取数据作为流,并过滤FuffyStase=“完成”的事件,并在某些输出主题或其他目的地发布。p> 例如:

KStream<String,JsonNode> inputStream= builder.stream(inputTopic);
KStream<String,JsonNode> completedFlowStream = inputStream.filter(value-> value.get("flow_status").equals("completed"));
KStream inputStream=builder.stream(inputopic);
KStream completedFlowStream=inputStream.filter(value->value.get(“flow_status”)。等于(“completed”);

p.S.Kafka没有针对KStream的Python API的正式版本,但有一个开源项目:

截至今天,无法在代理端实现它,有一个Jira功能请求向apache Kafka开放,以实现此功能,您可以在此处跟踪,我希望他们在不久的将来实现此功能:


我觉得最好的方法是使用RecordFilterStrategy(Java/spring)接口并在消费者端对其进行过滤。

这样我就可以有3个主题,1个用于整个日志,1个用于完成状态,1个用于故障状态。。。作业将写入主题1,然后根据状态将数据过滤到其他主题。确切地说,在这个用例中,您的状态是值得一个不同主题的消息类型(一个用于完成,一个用于失败)是一个好方法吗,一个主题有两个部分(一个用于完成,一个用于失败),发送时,将在生产者中保留逻辑,以便将数据发送到各自的分区。。。在使用者端,将创建独立的使用者组,一个组从失败的分区读取,另一个组从完成的分区读取生产者端可能很好是的,但您需要实现一个自定义分区器来实现这一点。在消费者方面,情况正好相反,两个消费者需要位于同一消费者组中,以便为每个消费者分配一个分区。如果它们属于不同的消费者组,那么它们将从两个分区获得所有消息。在任何情况下,它都不能正常工作,因为如果一个使用者崩溃,另一个将获得另一个分区(接收已完成和失败的消息)。您可以避免使用使用者组,而直接使用分区分配。