Flink-水印-主流与侧流输出

实际工作中,数据到来不会总是有序的,所以window需要结合水印来使用,以满足实际场景。但是既便用了水印,也有可能存在漏网之鱼,这时就要用到侧流来将漏网数据收住,提高数据精准度。

运行方法

1、将下述代码贴到工程里,注意需要依赖flink的相关包 2、调试步骤1:linux 打开 nc工具,启动控制台,准备数据输入 3、调试步骤2:启动工程,观察侧流与主流的数据

例子数据

yaml 复制代码
        /**
         * 1000,a,1
         * 2000,a,1
         * 4998,a,1
         * 4999,a,1
         * 6999,a,1
         * 12000,a,1
         * 当到了12000时,执行的时,第二个窗口内的数据
         * 第1个窗口:[0000,5000)
         * 第2个窗口:[5000,10000)
         * 注:flink窗口是左闭右开的
         */

代码如下

swift 复制代码
package com.flink.watermarks;


import cn.hutool.core.date.format.FastDateFormat;
import lombok.val;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.functions.ReduceFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor;
import org.apache.flink.streaming.api.functions.windowing.ProcessWindowFunction;
import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.util.Collector;
import org.apache.flink.util.OutputTag;

public class EventTimeWMApp {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        //env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);

        test01(env);
        env.execute("WindowApp");
    }

    /**
     * EventTime结合WM使用
     * 输入数据格式:时间字段、单词、次数
     * @param env
     */
    public static void test01(StreamExecutionEnvironment env){
        //用于接收延迟到来的数据(窗口已结束,还有相应的时间段的数据进来)
        OutputTag<Tuple2<String,Integer>> outputTag = new OutputTag<Tuple2<String,Integer>>("late-data"){};


        DataStreamSource<String> source = env.socketTextStream("localhost",9527);

        //开始建数据源时,直接建watermarker更好一些,而不是在过程中建。
        SingleOutputStreamOperator<String> lines = source.assignTimestampsAndWatermarks(
                new BoundedOutOfOrdernessTimestampExtractor<String>(Time.seconds(0)) {
                    //乱序的watermarker处理器
                    @Override
                    public long extractTimestamp(String element) {
                        return Long.parseLong(element.split(",")[0]);//获取数据中的第一列,被当成触发5秒一个窗口的时间序列(对比值)
                    }
                }
        );

        SingleOutputStreamOperator<Tuple2<String,Integer>>  mapStream = lines.map(new MapFunction<String, Tuple2<String,Integer>>(){
            @Override
            public Tuple2<String, Integer> map(String value) throws Exception {
                String[] splits = value.split(",");
                try{
                    return Tuple2.of(splits[1],Integer.parseInt(splits[2].trim()));
                }catch (Exception e){
                    e.printStackTrace();
                    return new Tuple2("null",Integer.MIN_VALUE);
                }
            }
        });

        /**
         * 1000,a,1
         * 2000,a,1
         * 4998,a,1
         * 4999,a,1
         * 6999,a,1
         * 12000,a,1
         * 当到了12000时,执行的时,第二个窗口内的数据
         * 第1个窗口:[0000,5000)
         * 第2个窗口:[5000,10000)
         * 注:flink窗口是左闭右开的
         */
        SingleOutputStreamOperator window =  mapStream.keyBy(x -> x.f0)
            .window(TumblingEventTimeWindows.of(Time.seconds(5)))
            //sideOutputLateData(OutputTag<T> outputTag) ,用于解决窗口结束,还有数据进来的情况
                .sideOutputLateData(outputTag)//接收延迟数据
            .reduce(new ReduceFunction<Tuple2<String, Integer>>() {
                @Override
                public Tuple2<String, Integer> reduce(Tuple2<String, Integer> v1, Tuple2<String, Integer> v2) throws Exception {
                    System.out.println(" ---reduce invoked ---" + v1.f0 + "[(" + v1.f1 + "," + v2.f1 + ")]===>" + (v1.f1 + v2.f1));
                    return Tuple2.of(v1.f0, v1.f1 + v2.f1);
                }//以增量的方式聚合
            }, new ProcessWindowFunction<Tuple2<String, Integer>, Object, String, TimeWindow>() {
                FastDateFormat format = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
                //双窗口的方式
                @Override
                public void process(String s, Context context, Iterable<Tuple2<String, Integer>> elements, Collector<Object> out) throws Exception {
                    for (Tuple2<String, Integer> element : elements) {
                        out.collect("[" + format.format(context.window().getStart()) + "]===> " + format.format(context.window().getEnd()) + "]," + element.f0 + "===>" + element.f1);
                        //});
                    } //窗口的开始时间
                }
            });
            //.sum(1)
            //主流数据
            window.print();

            //侧流数据
            DataStream<Tuple2<String,Integer>> sideOutput = window.getSideOutput(outputTag); //得到延迟数据
            sideOutput.print();

    }


}
相关推荐
喵个咪20 小时前
GoWind Admin 拆解:BI 大屏设计器——schema 即 JSON、resolver 注入与三张快照表的口径谱系
大数据·后端·go
武子康21 小时前
H3-World 的 11.3 小时训练数据,是怎样对齐成动作监督的?
大数据·人工智能·深度学习
字节跳动数据平台1 天前
火山引擎知识引擎VeKnow进化之路(下):让 AI 智能体更可用、更可信、更懂业务
大数据
Elastic 中国社区官方博客1 天前
更少的位数,相同的召回率:DiskBBQ 更保守的自动校准扫描
大数据·运维·开发语言·人工智能·elasticsearch·搜索引擎
MyBili1 天前
Chrome隐私安全配置:完整防护指南
大数据·chrome·谷歌浏览器·隐私安全·浏览器防护·cookie管理·上网痕迹清理
真上帝的左手1 天前
19. 大数据-数据同步-工具
大数据·数据同步
数字孪生视频孪生1 天前
在线重构,实时同步:视频动态三维重建打造 “常更常新” 的数字底座
大数据·人工智能·重构·架构·空间计算
Aloudata1 天前
Claude 做数据分析的这两年:一份复盘与发展线索
大数据·数据库·人工智能·数据挖掘·数据分析·dataagent
云上工程笔记1 天前
SRT字幕一键转手绘动画:srt-whiteboard-animation的复刻实录
大数据·开发语言·javascript·人工智能·机器学习
isNotNullX1 天前
仓储管理最全框架:6大流程、8项指标、10个管理动作、12个常见问题
大数据·人工智能