在分组和聚合

时间:2018-05-22 10:21:51

标签: java apache-kafka apache-kafka-streams message-hub

我有一个Kafka流,其中包含传入的消息 sensor_code: x, time: 1526978768, address: Y 我想创建一个KTable,在每个传感器代码中存储每个唯一的地址。

KTable

KTable<String, Long> numCount = streams
            .map(kvm1)
            .groupByKey(Serialized.with(stringSerde, stringSerde))
            .count()
            .groupBy(kvm2, Serialized.with(stringSerde, longSerde))
            .count(Materialized.<String, Long, KeyValueStore<Bytes, byte[]>>as("StateStore"));

kvm1kvm2是我自己的KeyValueMappers。我的想法是用sensor_code=x, address=y替换现有密钥,执行groupByKey()count()。然后另一个groupBy(kvm2, Serialized.with(stringSerde, longSerde)) kvm2修改现有key以包含sensor_code,然后该值将是其计数。但既然它不起作用,也许我做错了...... 它试图将其转换为Long并抛出异常,因为它正在寻找一个String。我希望计数为Long,对吗?

以下是我使用的第一个KeyValueMapper及其各自的帮助功能:

    private static String getKeySensorIdAddress(String o) {
    String x = "sensor_id=\"x\", address=\"y\""; 
    try {
        WifiStringEvent event = mapper.readValue(o, WifiStringEvent.class);
        x = x.replace("x", event.getSensor_code());
        x = x.replace("y", event.getAddress());
        return x;
    } catch(Exception ex) {
        System.out.println("Error... " + ex);
        return "Error";
    }
}
        //KeyValueMapper1
KeyValueMapper<String, String, KeyValue<String, String>> kvm1 = 
    new KeyValueMapper<String, String, KeyValue<String, String>>() {
         public KeyValue<String, String> apply(String key, String value) {
             return new KeyValue<>(getKeySensorIdAddress(value), value);
         }
    };

这是第二个KeyValueMapper及其帮助功能。

    private static String getKeySensorId(String o) {
    int a = o.indexOf(",");
    return o.substring(0,a);
}

        //KeyValueMapper2 
    KeyValueMapper<String, Long, KeyValue<String, Long>> kvm2 = 
    new KeyValueMapper<String, Long, KeyValue<String, Long>>() {
         public KeyValue<String, Long> apply(String key, Long value) {
             return new KeyValue<>(getKeySensorId(key), value);
         }
    };

以下是我尝试运行代码时返回的异常和错误。

  

[2018-05-29 15:28:40,119] ERROR stream-thread [testUniqueAddresses-ed48daf8-fff0-42e4-bb5a-687584734b45-StreamThread-1]由于以下错误,无法处理流任务2_0 :( org .apache.kafka.streams.processor.internals.AssignedStreamsTasks:105)   java.lang.ClassCastException:java.lang.Long无法强制转换为java.lang.String       在org.apache.kafka.common.serialization.StringSerializer.serialize(StringSerializer.java:28)       在org.apache.kafka.streams.state.StateSerdes.rawValue(StateSerdes.java:178)       在org.apache.kafka.streams.state.internals.MeteredKeyValueBytesStore $ 1.innerValue(MeteredKeyValueBytesStore.java:66)       在org.apache.kafka.streams.state.internals.MeteredKeyValueBytesStore $ 1.innerValue(MeteredKeyValueBytesStore.java:57)       在org.apache.kafka.streams.state.internals.InnerMeteredKeyValueStore.put(InnerMeteredKeyValueStore.java:198)       在org.apache.kafka.streams.state.internals.MeteredKeyValueBytesStore.put(MeteredKeyValueBytesStore.java:117)       在org.apache.kafka.streams.kstream.internals.KTableAggregate $ KTableAggregateProcessor.process(KTableAggregate.java:95)       在org.apache.kafka.streams.kstream.internals.KTableAggregate $ KTableAggregateProcessor.process(KTableAggregate.java:56)

请注意java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String错误。

任何想法为什么我会收到此错误以及如何修复它或建议如何编辑代码以达到我提到的所需输出?

非常感谢提前!

修改 我已经放弃了其中一种方法,对我的问题进行了重大改革。

1 个答案:

答案 0 :(得分:2)

在第一种情况下,如果要将HashMap用作值类型,则需要为其定义自定义serde并使用Materialized传递它。withValueSerde

在第二种情况下,我不能说没有看到KeyValueMappers中的返回类型和确切的错误消息:它是否尝试将String转换为Long,反之亦然?

编辑:感谢分享额外信息。

我认为在第二种情况下你需要的是在第二次计数操作中指定值serde。 KGroupedStream上的count()与KGroupedTable之间似乎存在不一致,因为前者自动将值serde设置为LongSerde:

https://github.com/apache/kafka/blob/1.1/streams/src/main/java/org/apache/kafka/streams/kstream/internals/KGroupedStreamImpl.java#L281-L283

但是KGroupedTable没有:

https://github.com/apache/kafka/blob/1.1/streams/src/main/java/org/apache/kafka/streams/kstream/internals/KGroupedTableImpl.java#L253

似乎已经在主干上修复但尚未发布:

https://github.com/apache/kafka/blob/trunk/streams/src/main/java/org/apache/kafka/streams/kstream/internals/KGroupedTableImpl.java#L158-L160