Flink学习笔记-窗口计算之WindowsAssigner

Windows在Flink中作为独立的Operator存在,其可以将无限的数据集按照时间或者长度进行切分,从而完成当前所关心数据的统计计算,满足流计算中相关业务场景。每个窗口算子中,包含了Windows Assigner、Windows Trigger、Evictor、Lateness。OutPutTag以及Windows Function等。其中Windows Assigner和Windows Function是所有窗口算子必须指定的的。

Keyed Windows&Non-Keyed Windows

keyed windows会将数据分区,最后计算出每个key(同一分区)的结果数据,例如:同一用户在某一段时间内的访问频次。而non-keyed则需要调用windowsAll来制定window assigner,所有数据都会在窗口算子中路由到一个Task中进行计算,并得到全局统计结果。
在这里插入图片描述

WindowsAssigner

Windows Assigner的作用是指定窗口的类型,定义如何将数据流分配到一个或者多个窗口,api中通过window (WindowsAssigner assigner)指定。在Flink中支持两种类型的窗口,一种是基于时间的窗口(timeWindow),另一种是基于数量的窗口(countWindow)。窗口所表现出的类型特性取决于window assigner的定义。

Assigner家族
在这里插入图片描述
Flink底层Window模型仅有TimeWindow以及GlobalWindow。
在这里插入图片描述

基于时间类型窗口

基于时间类型的窗口,Flink内置了常用的四种,其中包含:滑动窗口,滚动窗口,会话窗口,全局窗口;其中前三种最终的窗口还是TimeWindow模型,而全局窗口则是GlobalWindow模型。

  • 滚动窗口(Tumbling Windows):根据固定时间或大小进行切分,窗口与窗口之间元素互不重叠。DataStream Api中提供了基于Event Time和process Time两种时间类型的滚动窗口,对应的Assigner分别为TumblingEventTimeWindows,TumblingProcessingTimeWindows。例子如下:
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStreamSource<Tuple3<String, Integer, Long>> dataStreamSource = env.addSource(new MySourceFunction());
        DataStream<Tuple3<String, Integer, Long>> result = dataStreamSource.keyBy(0).
                window(TumblingEventTimeWindows.of(Time.seconds(10L))).sum(1);

该例中,窗口的时间按照10S进行切分,TumblingProcessingTimeWindows类似。我们还可以通过timeWindow()的方式定义Window Assigner,timeWindow是Flink对时间窗口做的一层封装,如下:
在这里插入图片描述
所以我们只需要指定构建Assigner所需的时间即可,因为时间类型,timeWindow会根据事先设定的时间概念来推断。例子如下:

       StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
        DataStreamSource<Tuple3<String, Integer, Long>> dataStreamSource = env.addSource(new MySourceFunction());
        DataStream<Tuple3<String, Integer, Long>> result = dataStreamSource.keyBy(0).
                timeWindow(Time.seconds(10L)).sum(1);

该例与上述常规window方法指定assigner的效果一样,均为按照事件时间10S切分。

  • 滑动窗口(Sliding Windows):滑动窗口只是在滚动窗口的基础上增加了窗口滑动时间(Slide Time),允许窗口数据发生重叠。简言之,当窗口的size固定之后,窗口会根据给定的Slide Time向前滑动,即窗口之间的数据重叠大小是根据window size和 Slide size来决定的。也就是说有可能会出现窗口不连续,数据可能不在任何一个窗口内,当slide size和windows size相等时,滑动窗口就降级为滚动窗口了。同样的,DataStream Api中也提供了基于Event Time和process Time两种时间类型的滑动窗口,例子如下:
   StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStreamSource<Tuple3<String, Integer, Long>> dataStreamSource = env.addSource(new MySourceFunction());
        DataStream<Tuple3<String, Integer, Long>> result = dataStreamSource.keyBy(0).
                window(SlidingEventTimeWindows.of(Time.minutes(5),Time.seconds(10))).sum(1);
        result.print();
        env.execute("qingh Demo");

想要使用process Time只需要将例子中SlidingEventTimeWindows改为SlidingProcessingTimeWindows即可。同样滴,例子Flink包装的方式(timeWindow)例子如下:

 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
        DataStreamSource<Tuple3<String, Integer, Long>> dataStreamSource = env.addSource(new MySourceFunction());
        DataStream<Tuple3<String, Integer, Long>> result = dataStreamSource.keyBy(0).
                timeWindow(Time.minutes(5),Time.seconds(10)).sum(1);
        result.print();
        env.execute("qingh Demo");

通过阅读timeWindow的实现,不难发现,本质上还是调用相应的window,无非就是简化一些操作。
在这里插入图片描述

  • 会话窗口(Session Windows):本质还是TimeWindow,将某段时间内活跃度比较高的数据聚合成一个窗口进行计算,窗口触发的条件是Session Gap,Session Gap规定了不活跃数据的时间上限。会话窗口适用于非连续型数据处理或者周期性产生数据的场景。同样滴,会话窗口也有基于Event Time和process Time两种时间类型的不同实现。 例子如下:
   StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStreamSource<Tuple3<String, Integer, Long>> dataStreamSource = env.addSource(new MySourceFunction());
        DataStream<Tuple3<String, Integer, Long>> result = dataStreamSource.keyBy(0).
                window(EventTimeSessionWindows.withGap(Time.minutes(10))).sum(1);
        result.print();
        env.execute("qingh Demo");

通过withGap来指定不活跃数据的时间周期(本例10m),想要使用process time只需将EventTimeSessionWindows替换为ProcessingTimeSessionWindows,会话窗口没有类似timeWindow的快捷构造方式

Flink还支持动态调整Session Gap,例子如下:

 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStreamSource<Tuple3<String, Integer, Long>> dataStreamSource = env.addSource(new MySourceFunction());
        DataStream<Tuple3<String, Integer, Long>> result = dataStreamSource.keyBy(0).
                window(ProcessingTimeSessionWindows.withDynamicGap(new SessionWindowTimeGapExtractor<Tuple3<String, Integer, Long>>() {
                    @Override
                    public long extract(Tuple3<String, Integer, Long> element) {
                    // 完成动态调整session grap的具体逻辑
                        return element.f2;
                    }
                })).sum(1);
        result.print();
        env.execute("qingh Demo");

实现Flink的SessionWindowTimeGapExtractor动态抽取器,然后复写抽取方法,将抽取器作为参数传入*TimeSessionWindows的withDynamicGap方法中即可完成动态调整Session Gap,具体逻辑在extract中完成。

由于Session Window本质上没有固定的起止时间,因此其底层计算逻辑和滑动、滚动窗口有一定的区别。Session Windows会为每一个进入的数据都创建一个窗口,最后将距离Session Gap最近的窗口进行合并计算窗口结果。因此对于Session Windows来说,需要能够合并的Trigger和Windows Function,比如ReduceFunction,AggregateFunction,ProcessWindowFunction等。

  • 全局窗口(Global Windows):将所有相同key的数据分配到单个窗口中计算结果,窗口没有起始和结束时间,需要借助Triger来触发计算,也就是说如果指定为全局窗口而不指定Triger则窗口是不会触发计算的,同时还需要指定数据清理机制,不然数据将一直存在于内存中。栗子:
	 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStreamSource<Tuple3<String, Integer, Long>> dataStreamSource = env.addSource(new MySourceFunction());
        DataStream<Tuple3<String, Integer, Long>> result = dataStreamSource.keyBy(0).
                window(GlobalWindows.create()).sum(1);
        result.print();
        env.execute("qingh Demo");

GlobalWindows负责维护GlobalWindow,通过create构造GlobalWindows,然后在调用assignWindows时,调用assignWindow的get方法获取唯一实例。
在这里插入图片描述
在这里插入图片描述

基于数量类型窗口

基于数量类型的窗口,flink通过GlobalWindows来支持countWindow,通过给GlobalWindows设置CountTrigger来实现滚动的count Window,通过设置CountEvictor,以及CountTrigger来实现滑动的count Windows。

  • 滚动数量类型窗口
    计数触发,栗子:
  StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStreamSource<Tuple3<String, Integer, Long>> dataStreamSource = env.addSource(new MySourceFunction());
        DataStream<Tuple3<String, Integer, Long>> result = dataStreamSource.keyBy(0).
                countWindow(10).sum(1);
        result.print();
        env.execute("qingh Demo");

其底层实现如图
在这里插入图片描述

  • 滑动数量类型窗口
   StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStreamSource<Tuple3<String, Integer, Long>> dataStreamSource = env.addSource(new MySourceFunction());
        DataStream<Tuple3<String, Integer, Long>> result = dataStreamSource.keyBy(0).
                countWindow(10,2).sum(1);
        result.print();
        env.execute("qingh Demo");

实现方式
在这里插入图片描述

自定义窗口类型

实现WindowAssigner,复写assignWindows设定窗口类型,复写getDefaultTrigger设定默认触发器。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
flink-shaded-hadoop3和flink-shaded-hadoop3-uber是Apache Flink项目中与Hadoop 3.x版本集成相关的两个模块。 首先,Hadoop是一个分布式计算框架,用于处理大规模数据。而Flink是一个快速而可扩展的流式处理引擎,它可以在实时和批处理任务之间无缝切换。为了与Hadoop集成,并且能够在Flink中使用Hadoop生态系统的各种功能和工具,例如HDFS、YARN和MapReduce等,Flink提供了与Hadoop版本兼容的特殊模块。 flink-shaded-hadoop3模块是Flink所提供的一个可防止与Hadoop 3.x版本依赖冲突的模块。在Flink应用程序中,当需要使用Hadoop 3.x相关功能时,可以将flink-shaded-hadoop3模块添加到项目的依赖中。该模块会将特定版本的Hadoop 3.x依赖项重新打包,以避免与Flink自身或其他依赖项产生冲突。这样一来,Flink就能够与Hadoop 3.x版本协同工作,平滑地使用Hadoop的功能。 而flink-shaded-hadoop3-uber模块则是更加完整和庞大的用于集成Hadoop 3.x版本的模块。它将包含Hadoop 3.x依赖的所有必需库和资源等,以便于使用和编译。相比于flink-shaded-hadoop3模块,flink-shaded-hadoop3-uber模块更像是一个“全能版”,其中包含了实现与Hadoop 3.x版本深度集成所需的所有组件。这使得开发人员能够方便地构建和部署Flink应用程序,并且在与Hadoop生态系统进行交互时更加方便。 总的来说,flink-shaded-hadoop3和flink-shaded-hadoop3-uber模块都是Flink为了与Hadoop 3.x版本无缝集成,提供的两个特殊模块。它们通过重新打包Hadoop依赖,解决了可能产生的冲突问题,使得Flink能够顺利使用并利用Hadoop的功能和工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值