Kafka Streams的内部异常来自哪里?

时间:2018-04-02 21:32:21

标签: apache-kafka-streams

我在尝试聚合KGroupedStream时遇到问题<字符串,TsdbObject> 其中TsdbObject是一个方法为Double getValue()的POJO。以下陈述 显示groupBy和尝试聚合:

KGroupedStream< String, TsdbObject > assets_grouped_by_parents =
    kstream.groupBy( group_by_parent_mapper, Serialized.with( Serdes.String(), tsdb_object_serde ) );

KTable< String, Double > sums_of_groups_by_parents = 
    assets_grouped_by_parents.aggregate( new SummerInitializer(), new SummerAggregator() );                                                  

聚合由以下类完成:

private class SummerAggregator implements Aggregator< String, TsdbObject, Double > {
    @Override
        public Double apply(String key, TsdbObject value, Double aggregate) {
    System.out.println( "SummerAggregator.apply:  key is " + key + ", value is " + value +
                ", aggregate is " + aggregate );
    return aggregate + value.getValue();
    }
}

private class SummerInitializer implements Initializer< Double > {
    @Override
        public Double apply() {
    // TODO Auto-generated method stub
    System.out.println( "SummerInitializer" );
    return 0.0;
    }
}

当我执行应用程序时,我得到以下异常:

Encountered the following error during processing: 
java.lang.ClassCastException: [B cannot be cast to java.lang.Double
    at com.ui.kafka.experiments.metrics.TsdbObjectRollUp$SummerAggregator.apply(TsdbObjectRollUp.java:1)
    at org.apache.kafka.streams.kstream.internals.KStreamAggregate$KStreamAggregateProcessor.process(KStreamAggregate.java:79)

KStreamAggregate中引用的行是:

// try to add the new new value
if (value != null) {
    newAgg = aggregator.apply(key, value, newAgg);
}

奇怪的是newAgg的值,应该是Double,是:

[0, 0, 0, 0, 0, 0, 0, 21]

当然不能施放给Double。 这个奇怪的价值来自哪里?

1 个答案:

答案 0 :(得分:0)

您需要使用可选参数DoubleSerde为结果值类型assets_grouped_by_parents.aggregate(...)传入Materialized.withValueSerde()

KTable<String, Double> sums_of_groups_by_parents = 
    assets_grouped_by_parents.aggregate(
        new SummerInitializer(),
        new SummerAggregator(),
        Materialized.withValueSerde(Serdes.DoubleSerde()));

如果未在配置中将密钥设置为默认serde,您可能还需要为密钥指定StringSerde