簡體   English   中英

Apache Flink Streaming窗口WordCount

[英]Apache Flink Streaming window WordCount

我有以下代碼來計數來自socketTextStream的單詞。 累計字數和時間窗口字數都需要。 該程序存在一個問題,即cumulateCounts始終與窗口計數相同。 為什么會發生此問題? 根據窗口計數來計算累積計數的正確方法是什么?

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
final HashMap<String, Integer> cumulateCounts = new HashMap<String, Integer>();

final DataStream<Tuple2<String, Integer>> counts = env
            .socketTextStream("localhost", 9999)
            .flatMap(new Splitter())
            .window(Time.of(5, TimeUnit.SECONDS))
            .groupBy(0).sum(1)
            .flatten();

counts.print();

counts.addSink(new SinkFunction<Tuple2<String, Integer>>() {
    @Override
    public void invoke(Tuple2<String, Integer> value) throws Exception {
        String word = value.f0;
        Integer delta_count = value.f1;
        Integer count = cumulateCounts.get(word);
        if (count == null)
            count = 0;
        count = count + delta_count;
        cumulateCounts.put(word, count);
        System.out.println("(" + word + "," + count.toString() + ")");
    }
});

您應該首先分組,然后將窗口應用於鍵控數據流(您的代碼在Flink 0.9.1上有效,但是Flink 0.10.0中的新API對此非常嚴格):

final DataStream<Tuple2<String, Integer>> counts = env
        .socketTextStream("localhost", 9999)
        .flatMap(new Splitter())
        .groupBy(0)
        .window(Time.of(5, TimeUnit.SECONDS)).sum(1)
        .flatten();

如果將窗口應用於非鍵控數據流,則在單台計算機上只有一個線程化的窗口運算符(即,沒有並行性)才能在整個流上構建窗口(在Flink 0.9.1中,此全局窗口)可以通過groupBy()划分為多個子窗口-但是,在Flink 0.10.0中,它將不再起作用)。 要計算字數,您需要為每個不同的鍵值構建一個窗口,即,首先獲取每個鍵值的子流(通過groupBy() ),然后在每個子流上應用窗口運算符(因此,您可以使用每個子流都有自己的窗口運算符實例,允許並行執行)。

對於全局(累計)計數,您可以簡單地應用groupBy().sum()構造。 首先,將流分為子流(每個鍵值一個)。 其次,您計算流上的總和。 由於流是以加窗,在總和計算(累計)和更新的每個進入的元組(更詳細地,總和具有零初始結果值並且將結果針對每個元組作為更新的result += tuple.value ) 。 每次調用sum后,都會發出新的當前結果。

在您的代碼中,不應使用特殊的接收器功能,而應執行以下操作:

counts.groupBy(0).sum(1).print();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM