[英]Kafka streams not using serde after repartitioning
我的 Kafka Streams 應用程序正在使用使用以下鍵值布局的 kafka 主題: String.class -> HistoryEvent.class
打印我當前的主題時,可以確認:
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic flow-event-stream-file-service-test-instance --property print.key=true --property key.separator=" -- " --from-beginning
flow1 -- SUCCESS #C:\Daten\file-service\in\crypto.p12
"flow1" 是String
鍵,后面的部分--
是序列化值。
我的流程是這樣設置的:
KStream<String, HistoryEvent> eventStream = builder.stream(applicationTopicName, Consumed.with(Serdes.String(),
historyEventSerde));
eventStream.selectKey((key, value) -> new HistoryEventKey(key, value.getIdentifier()))
.groupByKey()
.reduce((e1, e2) -> e2,
Materialized.<HistoryEventKey, HistoryEvent, KeyValueStore<Bytes, byte[]>>as(streamByKeyStoreName)
.withKeySerde(new HistoryEventKeySerde()));
因此,據我所知,我告訴它使用String
和HistoryEvent
serde 來使用主題,因為這就是主題中的內容。 然后我“重新設置”它以使用組合鍵,該組合鍵應該使用為HistoryEventKey.class
提供的 serde 存儲在本地。 據我了解,這將導致使用新密鑰創建一個額外的主題(可以在 kafka 容器中的主題列表中看到)。 這可以。
現在的問題是,即使在主題中只有一個文檔的干凈環境中,應用程序也無法啟動:
org.apache.kafka.streams.errors.StreamsException: Exception caught in process. taskId=0_0, processor=KSTREAM-SOURCE-0000000000, topic=flow-event-stream-file-service-test-instance, partition=0, offset=0
Caused by: org.apache.kafka.streams.errors.StreamsException: A serializer (key: org.apache.kafka.common.serialization.StringSerializer / value: HistoryEventSerializer) is not compatible to the actual key or value type (key type: HistoryEventKey / value type: HistoryEvent). Change the default Serdes in StreamConfig or provide correct Serdes via method parameters.
從消息中很難判斷問題究竟出在哪里。 它在我的基本主題中說,但這是不可能的,因為那里的鍵不是HistoryEventKey
類型。 既然我已經提供了一個用於SERDE HistoryEventKey
在reduce
,也不能與本地存儲。
唯一對我有意義的是它與導致重新排列和新主題的selectKey
操作有關。 但是,我無法弄清楚如何為該操作提供 serde。 我不想將其設置為默認值,因為它不是默認密鑰 serde。
我的 Kafka Streams 應用程序正在使用使用以下鍵值布局的 kafka 主題: String.class -> HistoryEvent.class
打印我當前的主題時,可以確認:
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic flow-event-stream-file-service-test-instance --property print.key=true --property key.separator=" -- " --from-beginning
flow1 -- SUCCESS #C:\Daten\file-service\in\crypto.p12
“flow1”是String
鍵,后面的部分--
是序列化值。
我的流程是這樣設置的:
KStream<String, HistoryEvent> eventStream = builder.stream(applicationTopicName, Consumed.with(Serdes.String(),
historyEventSerde));
eventStream.selectKey((key, value) -> new HistoryEventKey(key, value.getIdentifier()))
.groupByKey()
.reduce((e1, e2) -> e2,
Materialized.<HistoryEventKey, HistoryEvent, KeyValueStore<Bytes, byte[]>>as(streamByKeyStoreName)
.withKeySerde(new HistoryEventKeySerde()));
因此,據我所知,我告訴它使用String
和HistoryEvent
serde 來使用主題,因為這就是主題中的內容。 然后我“重新設置”它以使用組合鍵,該組合鍵應該使用為HistoryEventKey.class
提供的 serde 存儲在本地。 據我了解,這將導致使用新密鑰創建一個額外的主題(可以在 kafka 容器中的主題列表中看到)。 這可以。
現在的問題是,即使在主題中只有一個文檔的干凈環境中,應用程序也無法啟動:
org.apache.kafka.streams.errors.StreamsException: Exception caught in process. taskId=0_0, processor=KSTREAM-SOURCE-0000000000, topic=flow-event-stream-file-service-test-instance, partition=0, offset=0
Caused by: org.apache.kafka.streams.errors.StreamsException: A serializer (key: org.apache.kafka.common.serialization.StringSerializer / value: HistoryEventSerializer) is not compatible to the actual key or value type (key type: HistoryEventKey / value type: HistoryEvent). Change the default Serdes in StreamConfig or provide correct Serdes via method parameters.
從消息中很難判斷問題究竟出在哪里。 它在我的基本主題中說,但這是不可能的,因為那里的鍵不是HistoryEventKey
類型。 既然我已經提供了一個用於SERDE HistoryEventKey
在reduce
,也不能與本地存儲。
唯一對我有意義的是它與導致重新排列和新主題的selectKey
操作有關。 但是,我無法弄清楚如何為該操作提供 serde。 我不想將其設置為默認值,因為它不是默認密鑰 serde。
我的 Kafka Streams 應用程序正在使用使用以下鍵值布局的 kafka 主題: String.class -> HistoryEvent.class
打印我當前的主題時,可以確認:
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic flow-event-stream-file-service-test-instance --property print.key=true --property key.separator=" -- " --from-beginning
flow1 -- SUCCESS #C:\Daten\file-service\in\crypto.p12
“flow1”是String
鍵,后面的部分--
是序列化值。
我的流程是這樣設置的:
KStream<String, HistoryEvent> eventStream = builder.stream(applicationTopicName, Consumed.with(Serdes.String(),
historyEventSerde));
eventStream.selectKey((key, value) -> new HistoryEventKey(key, value.getIdentifier()))
.groupByKey()
.reduce((e1, e2) -> e2,
Materialized.<HistoryEventKey, HistoryEvent, KeyValueStore<Bytes, byte[]>>as(streamByKeyStoreName)
.withKeySerde(new HistoryEventKeySerde()));
因此,據我所知,我告訴它使用String
和HistoryEvent
serde 來使用主題,因為這就是主題中的內容。 然后我“重新設置”它以使用組合鍵,該組合鍵應該使用為HistoryEventKey.class
提供的 serde 存儲在本地。 據我了解,這將導致使用新密鑰創建一個額外的主題(可以在 kafka 容器中的主題列表中看到)。 這可以。
現在的問題是,即使在主題中只有一個文檔的干凈環境中,應用程序也無法啟動:
org.apache.kafka.streams.errors.StreamsException: Exception caught in process. taskId=0_0, processor=KSTREAM-SOURCE-0000000000, topic=flow-event-stream-file-service-test-instance, partition=0, offset=0
Caused by: org.apache.kafka.streams.errors.StreamsException: A serializer (key: org.apache.kafka.common.serialization.StringSerializer / value: HistoryEventSerializer) is not compatible to the actual key or value type (key type: HistoryEventKey / value type: HistoryEvent). Change the default Serdes in StreamConfig or provide correct Serdes via method parameters.
從消息中很難判斷問題究竟出在哪里。 它在我的基本主題中說,但這是不可能的,因為那里的鍵不是HistoryEventKey
類型。 既然我已經提供了一個用於SERDE HistoryEventKey
在reduce
,也不能與本地存儲。
唯一對我有意義的是它與導致重新排列和新主題的selectKey
操作有關。 但是,我無法弄清楚如何為該操作提供 serde。 我不想將其設置為默認值,因為它不是默認密鑰 serde。
我遇到了一個非常相似的錯誤消息,但我沒有 groupbys,而是加入了。 我在這里為下一個在谷歌上搜索的人發帖。
org.apache.kafka.streams.errors.StreamsException: ClassCastException while producing data to topic my-processor-KSTREAM-MAP-0000000023-repartition. A serializer (key: org.apache.kafka.common.serialization.StringSerializer / value: org.apache.kafka.common.serialization.StringSerializer) is not compatible to the actual key or value type (key type: java.lang.String / value type: com.mycorp.mySession). Change the default Serdes in StreamConfig or provide correct Serdes via method parameters (for example if using the DSL, `#to(String topic, Produced<K, V> produced)` with `Produced.keySerde(WindowedSerdes.timeWindowedSerdeFrom(String.class))`).
顯然,與原始問題相同,我不想更改默認的 serdes。
所以在我的情況下,解決方案是在連接中傳遞一個 Joined 實例,這將允許傳入 serdes。 請注意,錯誤消息指向一個repartition-MAP-...
這有點牽強附會,因為修復程序在其他地方。
我是如何修復它的(一個聯合的例子)
//...omitted ...
KStream<String,MySession> mySessions = myStream
.map((k,v) ->{
MySession s = new MySession(v);
k = s.makeKey();
return new KeyValue<>(k, s);
});
// ^ the mapping causes the repartition, you can not however specify a serde in there.
// but in the join right below, we can pass a JOINED instance and fix it.
return enrichedSessions
.leftJoin(
myTable,
(session, info) -> {
session.infos = info;
return session; },
Joined.as("my_enriched_session")
.keySerde(Serdes.String())
.valueSerde(MySessionSerde())
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.