Apache Flink将结果减少许多值,而不是一个值

时间:2018-12-05 02:03:00

标签: java apache bigdata apache-flink flink-streaming

我试图在WindowedStream上实现reduce,就像这样:

                .keyBy(t -> t.key)
            .timeWindow(Time.of(15, MINUTES), Time.of(1, MINUTES))
            .reduce(new ReduceFunction<TwitterSentiments>() {
                @Override
                public TwitterSentiments reduce(TwitterSentiments t2, TwitterSentiments t1) throws Exception {
                    t2.positive += t1.positive;
                    t2.neutral += t1.neutral;
                    t2.negative += t1.negative;

                    return t2;
                }
            });

我遇到的问题是,当我调用stream.print()时,我得到了很多值(每个TwitterSentiments对象看起来像一个值,而不是单个聚合对象。

我也曾尝试使用像这样的AggregationFunction,但存在相同的问题:

                .aggregate(new AggregateFunction<TwitterSentiments, Tuple3<Long, Long, Long>, Tuple3<Long, Long, Long>>() {
                @Override
                public Tuple3<Long, Long, Long> createAccumulator() {
                    return new Tuple3<Long, Long, Long>(0L,0L,0L);
                }

                @Override
                public Tuple3<Long, Long, Long> add(TwitterSentiments ts, Tuple3<Long, Long, Long> accumulator) {
                    return new Tuple3<Long, Long, Long>(
                            accumulator.f0 + ts.positive.longValue(),
                            accumulator.f1 + ts.neutral.longValue(),
                            accumulator.f2 + ts.negative.longValue()
                    );
                }

                @Override
                public Tuple3<Long, Long, Long> getResult(Tuple3<Long, Long, Long> accumulator) {
                    return accumulator;
                }

                @Override
                public Tuple3<Long, Long, Long> merge(Tuple3<Long, Long, Long> accumulator1, Tuple3<Long, Long, Long> accumulator2) {
                    return new Tuple3<Long, Long, Long>(
                            accumulator1.f0 + accumulator2.f0,
                            accumulator1.f1 + accumulator2.f1,
                            accumulator1.f2 + accumulator2.f1);
                }
            });

在这些聚合之后,stream.print()仍会输出许多记录的原因是什么?

2 个答案:

答案 0 :(得分:1)

看来我误解了使用键的原因。就我而言,我不需要KeyedStream,因为我希望每分钟只有一个输出,该输出包括所有记录减少为一个值的记录。我最终在.timeWindowAll上使用了SingleOutputStreamOperator,并且运行reduce现在可以正常工作了。

答案 1 :(得分:1)

如果每个键不需要结果,则可以使用timeWindowAll产生单个结果。但是,timeWindowAll不能并行运行。如果要以更可扩展的方式计算结果,可以执行以下操作:

    .keyBy(t -> t.key)
    .timeWindow(<time specification>)
    .reduce(<reduce function>)
    .timeWindowAll(<same time specification>)
    .reduce(<same reduce function>)

您可能希望Flink的运行时足够聪明,可以为您执行此并行预聚合(前提是您使用的是ReduceFunction或AggregateFunction),但事实并非如此。