Flink程序经过reduce聚合后不输出sink的问题

Flink程序经过reduce聚合后不输出sink的问题

一、最近提交的一版flink流式计算程序,经过EventTimeSessionWindows后进行了reduce聚合,完成计算完成后迟迟不sink输出结果。

记录下踩过的坑

程序很简单,直接上代码:

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

//模拟socket数据流
DataStream kafkaDataStreamSource = env.socketTextStream("localhost", 9999, "\n");

kafkaDataStreamSource
        .filter((FilterFunction) s -> {
            if (s.trim().equals("")) {
                return false;
            }
            return true;
        })
        .map((MapFunction) s -> JSON.parseObject(s, CarInfo.class))
        //设置数据的eventtime作为watermark,代码略
        .assignTimestampsAndWatermarks(new ADPunctuatedWatermarks())
        //设置聚合key
        .keyBy(CarInfo::getPhoneUID)
        //设置Session Window 200s
        .window(EventTimeSessionWindows.withGap(Time.seconds(200)))
        //聚合
        .reduce(new CarInfoReduceFunction())
        //输出打印
        .addSink(new SinkFunction() {
            @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())
.setParallelism(1)
...

这一就OK了

你可能感兴趣的:(Flink)