簡體   English   中英

如何根據來自另一個主題的響應讀取來自 Kafka 主題的消息

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

我在 Kafka 中有 2 個主題:MetaData 和 MasterData。 我正在使用 Kafka Listners 實時讀取數據。 有2種情況:

  1. 我必須先閱讀 MetaData 主題,然后再閱讀 MasterData 主題。
  2. 也有可能在 MetaData 主題中沒有新的 msg,但在 MasterData 主題中插入了一條消息。 在這種情況下,應該繼續使用 MasterData 主題。

螞蟻建議如何實現這一目標?

在評論中澄清之后,這是我的理解,您想要實現的目標:

您有一個類似系統的數據庫,來自 kafka 主題的元數據用於調整表結構。 然后實際數據進入主 kafka 主題,然后您希望將其插入表中。 換句話說:您想使用 kafka 定義數據的結構。

我不確定,如果這就是我所說的 Kafka 的常規用例,因為它旨在成為交換事件(即數據)的接口。 您嘗試做的是將系統用作定義數據結構的手段。 但這只是我的意見。

正如前面評論中所說,幾乎沒有辦法說一個主題中不會有消息。 您只能說:“還沒有”消息。 您“可以”做的可能是:當master主題中的消息到達時,您首先檢查meta主題,如果也有消息。 如果有,則應用數據結構中的更改,然后從主主題導入消息。

另一種選擇是使用 Kafka Streams 而不是原始消費者來將兩個主題組合在一起,例如通過join

無論如何,要定義數據結構,通常會使用 Avro 之類的東西,它為您提供架構演變等。 然后編寫您的應用程序以了解架構更改並相應地將它們應用於您的數據庫表。

更新:如何使用 Kafka Streams 解決

如上所述,使用 Kafka Streams 將是您的案例的可能解決方案。 讓我解釋一下,我在一些偽 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