How does Kafka Stream send final aggregation with KTable#Suppress?

牧云@^-^@ 提交于 2020-01-06 05:27:07

问题


What I'd like to do is this:

  1. Consume records from a topic
  2. count the values for each 1 sec window
  3. detect window whose records num < 4
  4. Send the FINAL result to another topic

I use suppress to send final result, but I got an error like this.

09:18:07,963 ERROR org.apache.kafka.streams.processor.internals.ProcessorStateManager  
- task [1_0] Failed to flush state store KSTREAM-AGGREGATE-STATE-STORE-0000000002: 
java.lang.ClassCastException: org.apache.kafka.streams.kstream.Windowed cannot be cast to java.lang.String
at org.apache.kafka.common.serialization.StringSerializer.serialize(StringSerializer.java:28)
at org.apache.kafka.streams.kstream.internals.suppress.KTableSuppressProcessor.buffer(KTableSuppressProcessor.java:86)
at org.apache.kafka.streams.kstream.internals.suppress.KTableSuppressProcessor.process(KTableSuppressProcessor.java:78)
at org.apache.kafka.streams.kstream.internals.suppress.KTableSuppressProcessor.process(KTableSuppressProcessor.java:37)
at org.apache.kafka.streams.processor.internals.ProcessorNode.process(ProcessorNode.java:115)
at org.apache.kafka.streams.processor.internals.ProcessorContextImpl.forward(ProcessorContextImpl.java:146)
.....

I think my code is the same as example in developer guide. What's the problem? My code here.

final KStream<String, String> views = builder.stream("fluent-newData");
final KTable<Windowed<String>, Long> anomalousUsers = views
    .map((key, value) -> {
       JSONObject message = JSONObject.fromObject(value);
       String[] strArry = message.getString("detail").split(",");
       return KeyValue.pair(strArry[0], value);
    })
    .groupByKey()
    .windowedBy(TimeWindows.of(Duration.ofSeconds(1))
    .grace(Duration.ofSeconds(20)))
    .count()
    .suppress(Suppressed.untilWindowCloses(unbounded()))
    .filter((windowedUserId, count) -> count < 4);

final KStream<String, String> anomalousUsersForConsole = anomalousUsers
    .toStream()
    .filter((windowedUserId, count) -> count != null)
    .map((windowedUserId, count) -> new KeyValue<>(windowedUserId.toString(), windowedUserId.toString() +" c:" + count.toString()));

anomalousUsersForConsole.to("demo-count-output", Produced.with(stringSerde, stringSerde));

回答1:


"Windowed cannot be cast to java.lang.String" usually thrown when you haven't specified serdes directly.

when you building stream(..), specify directly Consumed instance like the following:

builder.stream("fluent-newData", Consumed.with(Serdes.String(), Serdes.String()))

also for groupByKey() you need to pass Grouped like the following:

 .groupByKey(Grouped.with(Serdes.String(), Serdes.String()))


来源:https://stackoverflow.com/questions/54036328/how-does-kafka-stream-send-final-aggregation-with-ktablesuppress

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!