Flink:RichFlatMapFunktion上的ValueState始终返回null

时间:2017-10-23 20:14:03

标签: apache-flink flink-streaming

我尝试计算给定Tumbling窗口中找到的最高标签数量。

为此,我对主题标签进行了“字数统计”并总结了它们。这很好用。在此之后,我尝试在给定窗口中找到具有最高顺序的#标签。我为此使用RichFlatMapFunction,并使用ValueState来保存单个主题标签的当前最大外观,但这不起作用。 我调试了我的代码并发现ValueState“maxVal”的值在每个flatMap步骤“null”中。所以update()和value()方法在我的场景中不起作用。

我是否误解了RichFlatMap功能或其用法?

这是我的代码,除了最后一个flatmap函数之外的所有内容都按预期工作:

public class TwitterHashtagCount {

public static void main(String args[]) throws Exception {

    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment().setParallelism(1);
    DataStream<String> tweetsRaw = env.addSource(new TwitterSource(TwitterConnection.getTwitterConnectionProperties()));

    DataStream<String> tweetsGerman = tweetsRaw.filter(new EnglishLangFilter());

    DataStream<Tuple2<String, Integer>> tweetHashtagCount = tweetsGerman
            .flatMap(new TwitterHashtagFlatMap())
            .keyBy(0)
            .timeWindow(Time.seconds(15))
            .sum(1)
            .flatMap(new RichFlatMapFunction<Tuple2<String, Integer>, Tuple2<String, Integer>>() {

                private transient ValueState<Integer> maxVal;

                @Override
                public void open(Configuration parameters) throws Exception {
                    ValueStateDescriptor<Integer> descriptor =
                            new ValueStateDescriptor<>(
                                    // state name
                                    "max-val",
                                    // type information of state
                                    TypeInformation.of(Integer.class));
                    maxVal = getRuntimeContext().getState(descriptor);
                }

                @Override
                public void flatMap(Tuple2<String, Integer> value, Collector<Tuple2<String, Integer>> out) throws Exception {
                    Integer maxCount = maxVal.value();
                    if(maxCount == null) {
                        maxCount = 0;
                        maxVal.update(0);
                    }

                    if(value.f1 > maxCount) {
                        maxVal.update(maxCount);
                        out.collect(new Tuple2<String, Integer>(value.f0, value.f1));
                    }
                }
            });

    tweetHashtagCount.print();


    env.execute("Twitter Streaming WordCount");
}

}

1 个答案:

答案 0 :(得分:3)

我想知道为什么你共享的代码会运行。 sum(1)的结果是非键控流,并且您使用的托管状态接口需要键控流,并且将为每个键保留单独的状态实例。我很惊讶你没有收到错误的说法“Keyed状态只能在'keyed stream'上使用,即在'keyBy()'操作之后。”

由于您之前已经对流进行了窗口化,因此如果您在RichFlatMapFunction之前再次使用它(使用相同的密钥),则每个密钥将出现一次,并且maxVal将始终为null。

如果您的目标是在每个时间窗口中找到所有主题标签的最大值,那么这样的事情可能会达到您的意图:

tweetsGerman
    .flatMap(new TwitterHashtagFlatMap())
    .keyBy(0)
    .timeWindow(Time.seconds(15))
    .sum(1)
    .timeWindowAll(Time.seconds(15))
    .max(1)