4.时间与窗口

news/2025/3/19 7:19:40/

4.1 时间类型

在Flink中定义了3种时间类型:

  • 事件时间(Event Time):事件的发生事件,数据本身自带时间字段。
  • 处理时间(Processing Time):计算引擎处理时的系统时间。
  • 和摄取时间(Ingestion Time):指事件进入流处理系统的时间。

4.2 窗口类型

  • 计数窗口(Count Window):滚动/滑动
  • 时间窗口(Time Window):滚动/滑动
  • 会话窗口(Session Window):当超过一段时间,该窗口没有收到新的数据元素,则视为该窗口结束。

4.3 窗口原理与机制

  1. 数据流进入算子前,被提交给WindowAssigner,决定元素被放到哪个或哪些窗口,同时可能会创建新窗口或者合并旧的窗口。
  2. 每一个窗口都拥有一个属于自己的触发器Trigger,每当有元素被分配到该窗口,或者之前注册的定时器超时时,Trigger都会被调用。
  3. Trigger被触发后,窗口中的元素集合就会交给Evictor(如果指定了),遍历窗口中的元素列表,并决定最先进入窗口的多少个元素需要被移除。
  4. 窗口函数计算结果值,发送给下游。

PS:Flink对一些聚合类的窗口计算(如sum和min)做了优化,因为只需要保存一个中间结果值。每个进入窗口的元素都会执行一次聚合函数并修改中间结果值。

(1)WindowAssigner:决定某个元素被分配到哪个/哪些窗口中去。

(2)WindowTrigger:拥有定时器,决定窗口何时触发/清除。处理时间和计数窗口的实现基于触发器完成。(事件时间窗口触发:watermark ≥ 窗口endTime

(3)WindowEvictor:窗口数据的过滤器,可在WindowFunction执行前或后,从Window中过滤元素。

1)CountEvictor: 计数过滤器。在Window中保留指定数量的元素,并从窗口头部开始丢弃其余元素。 2)DeltaEvictor: 阈值过滤器。本质上来说就是一个自定义规则,计算窗口中每个数据记录,然后与一个事先定义好的阈值做比较,丢弃超过阈值的数据记录。 3)TimeEvictor: 时间过滤器。保留Window中最近一段时间内的元素,并丢弃其余元素。

(4)Window函数:

1)增量计算函数:数据到达后立即计算,窗口只保存中间结果。效率高,性能好,但不够灵活。

2)全量计算函数:缓存窗口的所有元素,触发后统一计算,效率低,但计算灵活。

4.4 水印

水印(Watermark)用于处理乱序事件。(也就是迟到数据)

4.4.1 watermark生成

  1. Datastream watermark生成
    1. Source function中生成
    2. DataStream API中生成
      1. AssignerWithPeriodicWatermarks:系统周期性的调用getCurrentWatermark()来获取当前的Watermark,它返回的Watermark仅在大于上一次返回的Watermark情况下有效
        1. BoundedOutOfOrdernessTimestampExtractor:初始化Watermark = Long.MIN_VALUE,对每条数据,根据extractTimestamp获取最大时间戳currentMaxTimestamp。周期性的调用getCurrentWatermark获取当前最新的Watermark。Watermark=当前收到的数据元素的最大 时间戳-固定延迟
        2. AscendingTimestampExtractor:默认是顺序数据,Watermark=当前收到的数据元素的时间戳-1。减1的目的是确保有最大时间戳的事件不会被当做迟到数据丢弃(书上说 -1 是为了确保有最大时间戳的事件不会被当做迟到数据丢弃,私认为不对,窗口是左闭右开的,最大时间戳的事件会被分配给下一个窗口,此时上一个窗口触发,不代表会丢弃这条数据,因为是在下一个窗口触发时计算
        3. IngestionTimeExtractor:周期性调用getCurrentWatermark() 获取当前机器时间作为当前的Watermark。
      2. AssignerWithPunctuatedWatermarks:对每一条数据生成一个watermark,它返回的Watermark仅在大于上一次返回的Watermark情况下有效
  2. Flink SQL:与Datastream类似,主要是在TableSource中完成。

在实际的生产中Punctuated方式在TPS很高的场景下会产生大量的Watermark,会对下游算子造成一定计算压力,适用于实时性要求较高和TPS低的场景。

周期性适用于实时性要求不高,和TPS高的场景。

4.4.2 多流watermark

Apache Flink 内部要保证Watermark保持单调递增。存在多source watermark不一致的问题。

 

经过keyBy、partition之后,在Flink的底层执行模型上,多流输入会被分解为多个双流输入。下游watermark 取所有上游的最小值

4.5 时间服务

4.5.1 定时器服务

定时器服务在Flink中叫作TimerService,TimeService是在算子中提供定时器的管理行为, 包含定时器的注册和删除。在算子中使用时间服务来创建定时器(Timer),并且 在Timer触发的时候进行回调,从而进行业务逻辑处理。

4.5.2 定时器

定时器在Flink中叫作Timer。注册Timer然后重写其onTimer()方法,在Watermark超过Timer的时间点之后,触发回调onTimer()。

  • 对于事件时间,会根据Watermark,从事件时间的定时器队列中找到比给定时间小的所有定时器,触发该Timer所在的算子,然后由算子去调用UDF中的onTime()方法
  • 处理时间是从处理时间 Timer优先级队列中找到Timer。处理时间因为依赖于当前系统,所以其使用的是周期性调度。

4.5.3 优先队列

Flink自己实现了优先级队列来管理Timer,共有2种实现。

  • 基于堆内存的优先级队列HeapPriorityQueueSet:基于Java堆 内存的优先级队列,其实现思路与Java的PriorityQueue类似,使用了二叉树。
  • 基于RocksDB的优先级队列:分为Cache+RocksDB量级,Cache 中保存了前N个元素,其余的保存在RocksDB中。写入的时候采用 Write-through策略,即写入Cache的同时要更新RocksDB中的数据,可 能需要访问磁盘。

基于堆内存的优先级队列比基于RocksDB的优先级队列性能好,但 是受限于内存大小,无法容纳太多的数据;基于RocksDB的优先级队列 牺牲了部分性能,可以容纳大量的数据。

4.6 窗口实现

在 Flink 中 有 3 类 窗 口 : CountWindow 、 TimeWindow 、 SessionWindow,其执行时的算子是WindowOperator。

事件窗口用的比较少。在Flink中提供了4种Session Window的默认实现。

  1. ProcessingTimeSessionWindows:处理时间会话窗口,使用固定会话间隔时长。
  2. DynamicProcessingTimeSessionWindows : 处理时间会话窗口,使用自定义会话间隔时长。
  3. EventTimeSessionWindows:事件时间会话窗口,使用固定会话间隔时长。
  4. DynamicEventTimeSessionWindows:事件时间会话窗口,使用自定义会话间隔时长。

对于会话窗口,因为无法事先确定窗口的长度,也不知道该将数据元素放到哪个窗口,所以对于每一个事件分配一个SessionWindow。然后判断窗口是否需要与已有的窗口进行合并。窗口合并时按照窗口的起始时间进行排序,然后判断窗口之间是否存在时间重叠,重叠的窗口进行合并。


http://www.ppmy.cn/news/1016495.html

相关文章

OLAP与OLTP的异同、定义及优劣

OLAP与OLTP的异同、定义及优劣 OLAP:联机分析处理定义应用场景优缺点 OLTP:联机事物处理定义应用场景优缺点 OLTP与OLAP异同点相同点不同点例子 OLAP:联机分析处理 定义 OLAP(Online Analytical Processing,联机分析…

七月算法笔记

动态规划 动态规划解决的问题有 背包问题 01背包 多重背包 完全背包问题 打家劫舍 股票问题 子序列问题动态规划的本质性解题步骤 1.dp数组的含义,以及下标的含义 //到底是定义一维的dp数组 还是二维的dp数组 求子序列 求背包 二维数组 i j都是什么意思&#xff1…

如何在MongoDB中添加新用户

如何在MongoDB中添加新用户? MongoDB是一款流行的NoSQL数据库,它的可扩展性强,可进行分布式部署,且具有高可用性。其许多优势使得越来越多的企业和组织选择MongoDB作为其数据库系统。本文将介绍如何在MongoDB中添加新用户。 第一步…

UML-活动图

目录 一.活动图概述: 1.活动图的作用: 2.以下场合不使用活动图: 3.活动图的基本要素: 4.活动图的图符 4.1起始状态 4.2终止状态 4.3状态迁移 4.4决策点 4.5同步条:表示活动之间的不同 5.活动图: 二.泳道: 1.泳道图&a…

在java中操作redis_Data

1.引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency> 2.配置Redis数据源 redis:host: ${sky.redis.host}port: ${sky.redis.port}password: ${sk…

How Many Tables

一、题目 Today is Ignatius’ birthday. He invites a lot of friends. Now it’s dinner time. Ignatius wants to know how many tables he needs at least. You have to notice that not all the friends know each other, and all the friends do not want to stay with …

__dict__属性

__dict__ 是 Python 中的一个特殊属性&#xff0c;通常存在于大多数 Python 对象中&#xff0c;用于存储该对象的可变属性。 以下是关于 __dict__ 的一些关键点和详细信息&#xff1a; 存储属性&#xff1a;对于大多数自定义的 Python 对象&#xff0c;__dict__ 属性包含了这个…

安全杂记 - Linux文本三剑客之awk

目录 1.什么是AWK2.正则表达式3.语法4.内置变量示例printf命令5.复现awk经典实例(1).插入几个新字段(2).格式化空白(3).筛选IPv4地址(4).筛选给定时间范围内的日志 1.什么是AWK awk、grep、sed是linux操作文本的三大利器&#xff0c;合称文本三剑客。三者的功能都是处理文本&a…