简体   繁体   English

如何根据来自另一个主题的响应读取来自 Kafka 主题的消息

[英]how to read message from Kafka topic based on response from another topic

I have 2 topics in Kafka: MetaData and MasterData.我在 Kafka 中有 2 个主题:MetaData 和 MasterData。 And I am reading data in real time using Kafka Listners.我正在使用 Kafka Listners 实时读取数据。 There are 2 scenarios:有2种情况:

  1. I have to read MetaData topic first and then MasterData topic.我必须先阅读 MetaData 主题,然后再阅读 MasterData 主题。
  2. There could also be a possibility that no new msg comes in MetaData topic, but a message is inserted in MasterData topic.也有可能在 MetaData 主题中没有新的 msg,但在 MasterData 主题中插入了一条消息。 In such as case consumption from MasterData topic should go ahead.在这种情况下,应该继续使用 MasterData 主题。

Ant suggestions how to achieve this??蚂蚁建议如何实现这一目标?

After the clarification in the comments this is, what I understand, what you want to achieve:在评论中澄清之后,这是我的理解,您想要实现的目标:

You have a database like system, and the meta data from the kafka topic is used to adjust the table structure.您有一个类似系统的数据库,来自 kafka 主题的元数据用于调整表结构。 Then the actual data comes into the master kafka topic which you then want to insert into the table.然后实际数据进入主 kafka 主题,然后您希望将其插入表中。 In other words: You want to define the structure of your data using kafka.换句话说:您想使用 kafka 定义数据的结构。

I am not sure, if that's what I would call a regular use case for Kafka, as it is meant to be an interface to exchange events, aka data.我不确定,如果这就是我所说的 Kafka 的常规用例,因为它旨在成为交换事件(即数据)的接口。 What you try to do, is to use the system as a means of defining data structure.您尝试做的是将系统用作定义数据结构的手段。 But that's only my opinion.但这只是我的意见。

As said earlier in the comments, there is practically no way to say that there won't be a message in one topic.正如前面评论中所说,几乎没有办法说一个主题中不会有消息。 You can only say: there is no message "yet".您只能说:“还没有”消息。 What you "could" probably do is: When a message in the master topic arrives, you first check the meta topic, if there is a message, too.您“可以”做的可能是:当master主题中的消息到达时,您首先检查meta主题,如果也有消息。 If there is, you apply the changes in data structure, then import the message fron the master topic.如果有,则应用数据结构中的更改,然后从主主题导入消息。

Another option would be to use Kafka Streams instead of the raw consumers to bring together the two topics, with a join for example.另一种选择是使用 Kafka Streams 而不是原始消费者来将两个主题组合在一起,例如通过join

Anyway to define the data structure, one would normally use something like Avro, which gives you schema evolution and more.无论如何,要定义数据结构,通常会使用 Avro 之类的东西,它为您提供架构演变等。 Then write your application to be aware of schema changes an apply them to your database tables accordingly.然后编写您的应用程序以了解架构更改并相应地将它们应用于您的数据库表。

UPDATE: How to solve using Kafka Streams更新:如何使用 Kafka Streams 解决

As mentioned above, the use of Kafka Streams would be a possible solution to your case.如上所述,使用 Kafka Streams 将是您的案例的可能解决方案。 Let me explain, what i mean in some pseudo kafka streams code:让我解释一下,我在一些伪 kafka 流代码中的意思是:

import org.apache.kafka.streams.StreamsBuilder;
import org.apache.kafka.streams.kstream.GlobalKTable;

import java.nio.charset.StandardCharsets;

/**
 * Just an incomplete Kafka Streams Code Demo to show how the problem could
 * be solved with this framework instead of using the consumers directly.
 * Kafka Streams Boilerplate code not included.
 */
public class Example {
    private static final String META_TOPIC = "meta";
    private static final String MASTER_TOPIC = "master";

    // You have to make sure, the meta data is stored under this
    // specific key in the meta topic.
    private static final byte[] META_KEY = MetaEvent.class.getName().getBytes(StandardCharsets.UTF_8);

    public static void main(String[] args) {
        new Example().createTopology();
    }

    public void createTopology() {

        final StreamsBuilder builder = new StreamsBuilder();

        final GlobalKTable<byte[], MetaEvent> metaTable = builder.globalTable(META_TOPIC);

        builder.<byte[], MasterEvent>stream(MASTER_TOPIC)
                .leftJoin(
                        metaTable,
                        (k, v) -> META_KEY,
                        MasterWithMeta::new)
                .foreach(this::handleEvent);
    }

    private void handleEvent(byte[] key, MasterWithMeta masterWithMeta) {
        // 1) check if meta has changed, if so, apply changes to database
        // 2) import master data to database
    }
}

class MasterWithMeta {
    private final MasterEvent master;
    private final MetaEvent meta;

    public MasterEvent getMaster() {
        return master;
    }

    public MetaEvent getMeta() {
        return meta;
    }

    public MasterWithMeta(MasterEvent master, MetaEvent meta) {
        this.master = master;
        this.meta = meta;
    }

    public static MasterWithMeta create(MasterEvent master, MetaEvent meta) {
        return new MasterWithMeta(master, meta);
    }
}

class MetaEvent {
    // ...
}

class MasterEvent {
    // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM