繁体   English   中英

重新分区后,Kafka 流不使用 serde

[英]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()));

因此,据我所知,我告诉它使用StringHistoryEvent 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 HistoryEventKeyreduce ,也不能与本地存储。

唯一对我有意义的是它与导致重新排列和新主题的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()));

因此,据我所知,我告诉它使用StringHistoryEvent 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 HistoryEventKeyreduce ,也不能与本地存储。

唯一对我有意义的是它与导致重新排列和新主题的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()));

因此,据我所知,我告诉它使用StringHistoryEvent 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 HistoryEventKeyreduce ,也不能与本地存储。

唯一对我有意义的是它与导致重新排列和新主题的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.

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