簡體   English   中英

在一段時間內使用 kafka-streams 處理和檢查事件

[英]Process and check event using kafka-streams during some period

我有一個 KStream eventsStream,它從主題“事件”中獲取數據。 有兩種類型的事件,它們的鍵:
1. {user_id = X, event_id = 1} {..value, include time_event...}
2. {user_id = X, event_id = 2} {..value, include time_event...}

如果在 10 分鍾內沒有用戶提供event_id = 2的事件,我需要將event_id = 1事件遷移到主題“結果”。

例如,
1. 第一種情況:我們得到數據{user_id = 100, event_id = 1} {.. time_event = xxxx ...}並且在 10 分鍾內沒有事件{user_id = 100, event_id = 2} {.. time_event = xxxx + 10 minutes...} ,所以我們將其寫入 results-topic
2. 第二種情況:我們得到數據{user_id = 100, event_id = 1} {.. time_event = xxxx ...}和一個 10 分鍾內的事件{user_id = 100, event_id = 2} {.. time_event = xxxx + 5 minutes...} ,所以我們不會把它寫到 results-topic

如何使用 kafka-streams 在 java 代碼中實現這種行為?

我的代碼:

公共類結果流{

public static KafkaStreams newStream() {

    Properties properties = Config.getProperties("ResultStream");

    Serde<String> stringSerde = Serdes.String();

    StreamsBuilder builder = new StreamsBuilder();

    StoreBuilder<KeyValueStore<String, String>> store =
            Stores.keyValueStoreBuilder(
                    Stores.inMemoryKeyValueStore("inmemory"),
                    stringSerde,
                    stringSerde
            );
    builder.addStateStore(store);

    KStream<String, String> resourceEventStream = builder.stream(EVENTS.topicName(), Consumed.with(stringSerde, stringSerde));
    resourceEventStream.print(Printed.toSysOut());

    resourceEventStream.process(() -> new CashProcessor("inmemory"), "inmemory");
    resourceEventStream.process(() -> new FilterProcessor("inmemory", resourceEventStream), "inmemory");

    Topology topology = builder.build();

    return new KafkaStreams(topology, properties);

}

}

公共類 FilterProcessor 實現 Processor {

private ProcessorContext context;
private String eventStoreName;
private KeyValueStore<String, String> eventStore;
private KStream<String, String> stream;

public FilterProcessor(String eventStoreName, KStream<String, String> stream) {
    this.eventStoreName = eventStoreName;
    this.stream = stream;
}

@Override
public void init(ProcessorContext processorContext) {
    this.context = processorContext;
    eventStore = (KeyValueStore) processorContext.getStateStore(eventStoreName);
}

@Override
public void process(Object key, Object value) {

    this.context.schedule(Duration.ofMinutes(1), PunctuationType.WALL_CLOCK_TIME, timestamp -> {

        System.out.println("Scheduler is working");

        stream.filter((k, v) -> {

            JsonObject events = new Gson().fromJson(k, JsonObject.class);
            if (***condition***) {
                return true;
            }

            return false;
        }).to("results");
    });
}

@Override
public void close() {

}

}

CashProcessor 的作用只是將事件放到本地存儲中,如果有相同用戶的 event_id = 2,則用戶刪除 event_id = 1 的記錄。

FilterProcess 應該每分鍾使用本地存儲過濾事件。 但是我無法正確調用此處理(正如我實際上所做的那樣)...

我真的需要幫助。

為什么將KStream傳遞到處理器中? 這不是 DSL 的工作方式。

當您已經通過resourceEventStream.process() “連接”處理器時FilterProcessor#process(key, value)將自動為流中的每條記錄調用FilterProcessor#process(key, value)方法——但是, KStream#process()是一個終端操作,並且因此不允許您向下游發送任何數據。 相反,您可能想要使用transform() (這與process()加上輸出KStream基本相同)。

要在標點符號中實際向下游轉發數據,您應該使用通過init()方法提供的ProcessorContext使用context.forward()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM