[英]How to set multiple consumers in the same topic in Kafka using Quarkus
[英]How to use multiple transformers using the same topic for kafka streams?
我需要使用多個轉換器解析 kafka 上的復雜消息。 每個轉換器解析消息的一部分,並通過在消息上填充一些屬性來編輯消息。 最后,完全解析的消息使用 Kafka 消費者存儲在數據庫中。 目前,我正在這樣做:
streamsBuilder.stream(Topic.A, someConsumer)
\\ filters messages that have unparsed parts of type X
.filter(filterX)
\\ transformer that edits the message and produces new Topic.E messages
.transform(ParseXandProduceE::new)
.to(Topic.A, someProducer)
streamsBuilder.stream(Topic.A, someConsumer)
\\ filters messages that have unparsed parts of type Y
.filter(filterY)
\\ transformer that edits the message and produces new Topic.F messages
.transform(ParseYandProduceF::new)
.to(Topic.A, someProducer)
變壓器看起來像:
class ParseXandProduceE implements Transformer<...> {
@Override
public KeyValue<String, Message> transform (String key, Message message) {
message.x = parse(message.rawX);
context.forward(newKey, message.x, Topic.E);
return KeyValue.pair(key, message);
}
}
然而,這很麻煩,相同的消息在這些流中流動多次。 此外,還有一個消費者將topic.A
的消息存儲在數據庫中。 消息當前存儲多次,在每次轉換之前和每次轉換之后。 有必要將每條消息存儲一次。
以下可能有效,但似乎不利,因為每個過濾器+轉換塊都可以干凈地放在其自己的單獨 class 中:
streamsBuilder.stream(Topic.A, someConsumer)
\\ transformer that filters and edits the message and produces new Topic.E + Topic.F messages
.transform(someTransformer)
.to(Topic.B, someProducer)
並讓持久性消費者聽Topic.B
。
后者提出的解決方案是go,還是有其他方法可以達到相同的結果? 也許有源和匯的完整拓撲配置? 如果是這樣,這種情況會是什么樣子?
使用單個變壓器似乎是最簡單的解決方案。 因為您有兩個獨立的過濾器,所以如果您嘗試鏈接各個運算符,程序將變得更加復雜。 如果您知道每條消息只會通過一個過濾器,而不會同時通過兩個過濾器,則可以使用branch()
:
KStream[] subStreams = stream.branch(new Predicates[]{filterX,filterY});
subStream[0].transform(ParseXandProduceE::new)
.merge(subStream[1].transform(ParseYandProduceF::new)
.to(...)
請注意,上述解決方案僅在兩個轉換器都不需要轉換任何消息時才有效( branch()
將每條消息放入第一個匹配謂詞的分支中,但絕不會放入多個分支中)。 因此,如果一條消息可以通過兩個過濾器,則您需要做一些更復雜的事情:
KStream[] subStreams = stream.branch(new Predicates[]{filterX,filterY});
KStream passedX = subStreams[0];
KStream transformedXE = passedX.transform(ParseXandProduceE::new);
// a message that passed filterX may also pass filterY,
// and thus we merge those message back to the "y-stream"
// (of course, those messages would already be transformed by `ParseXandProduceE`)
KStream passedY = subStream[1].merge(transformedXE.filter(filterY);
// the result contains all message that only pass filterX and got transformed,
// plus all messages that passed filterY (and maybe also filterX) and got transformed
KStream result = transformedXE.filterNot(filterY)
.merge(passedY.transform(ParseYandProduceF::new)
result.to(...)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.