Flink程序經過reduce聚合後不輸出sink的問題

Flink程序經過reduce聚合後不輸出sink的問題

一、最近提交的一版flink流式計算程序,經過EventTimeSessionWindows後進行了reduce聚合,完成計算完成後遲遲不sink輸出結果。

記錄下踩過的坑

程序很簡單,直接上代碼:

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(5);
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

//模擬socket數據流
DataStream<String> kafkaDataStreamSource = env.socketTextStream("localhost", 9999, "\n");

kafkaDataStreamSource
        .filter((FilterFunction<String>) s -> {
            if (s.trim().equals("")) {
                return false;
            }
            return true;
        })
        .map((MapFunction<String, CarInfo>) s -> JSON.parseObject(s, CarInfo.class))
        //設置數據的eventtime作爲watermark,代碼略
        .assignTimestampsAndWatermarks(new ADPunctuatedWatermarks<CarInfo>())
        //設置聚合key
        .keyBy(CarInfo::getPhoneUID)
        //設置Session Window 200s
        .window(EventTimeSessionWindows.withGap(Time.seconds(200)))
        //聚合
        .reduce(new CarInfoReduceFunction<CarInfo>())
        //輸出打印
        .addSink(new SinkFunction<CarInfo>() {
            @Override
            public void invoke(CarInfo value, Context context) throws Exception {
                System.out.println(JSON.toJSONString(value));
            }
        });
        

測試發現reduce函數輸出正常,可以正常聚合,但就是不走sink;

最終發現是因爲併發度大於1的問題,多個併發時不同的數據可能走到了不同的數據通道,導致無法觸發session window 的條件,故無法輸出。

解決方案
1、可以設置全局併發度爲1:
env.setParallelism(1);

2、設置watermark並行度爲1:在assignTimestampsAndWatermarks後面添加

...
.assignTimestampsAndWatermarks(new ADPunctuatedWatermarks<CarInfo>())
.setParallelism(1)
...

這一就OK了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章