Flink之对时间的处理
window+trigger+watermark处理全局乱序数据,指定窗口上的allowedLateness可以处理特定窗口操作的局部事件时间乱序数据
1、流处理系统中的微批
Flink内部也使用了某种形式的微批处理技术,在shuffle阶段将含有多个事件的缓冲容器通过网络发送,而不是发送单个事件
流处理系统中的批处理必须满足以下两点要求:
- 批处理只作为提高系统性能的机制。批量越大,系统的吞吐量就越大。
- 为了提高性能而使用的批处理必须完全独立于定义窗口时所用的缓冲,或者为了保证容错性而提交的代码,也不能作为 API 的一部分。否则,系统将受到限制,并且变得脆弱且难以使用。
2、时间概念
- 事件时间,即事件实际发生的时间(由水印触发器实现),基于事件时间处理可实现时间回溯并正确地重新处理数据
- 处理时间,即事件被处理的时间,是处理事件的机器所测量的时间
- 摄取时间,即事件进入流处理框架的时间,缺乏事件时间的数据会被处理器附上摄取时间(由source函数完成)
3、窗口
所有内置窗口都由同一种机制实现,开窗机制与检查点机制完全分离;可直接用基本的开窗机制定义更复杂的窗口(如某种时间窗口,可基于元素计数生成中间结果)
窗口时间区间是按自然时间分配的,比如3秒的时间间隔,[0,3) [3,6)
(1)时间窗口(每隔B时长对A时长内数据聚合)
- 设置事件时间 env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
- 设置处理时间 env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime)
- 设置摄取时间 env.setStreamTimeCharacteristic(TimeCharacteristic.IngestionTime)
- 滚动窗口A stream.timeWindow(Time.minutes(1)) stream.window(TumblingEventTimeWindows.of(Time.seconds(1)))
- 滑动窗口B stream.timeWindow(Time.minutes(1), Time.seconds(30)) stream.window(TumblingEventTimeWindows.of(Time.seconds(1)), SlidingEventTimeWindows.of(Time.seconds(30)))
(2)计数窗口(每隔B个元素对A个元素进行聚合)
为避免永远达不到计数窗口而浪费内存,可用时间窗口触发超时
- 滚动窗口A stream.countWindow(4)
- 滑动窗口B stream.countWindow(4, 2)
(3)会话窗口(会话即活动阶段,其前后都是非活跃阶段,常用于无固定持续时间或无固定交互次数的场景)
由超时时间设定,即希望非活跃状态持续多久才结束窗口。window区间:当b比上一条记录a延迟超过超时时间t时,出现会话窗口[上一个window_end, b-t)
- 事件时间会话窗口 stream.window(EventTimeSessionWindows.withGap(Time.minutes(5))
- 处理时间会话窗口 stream.window(ProcessingTimeSessionWindows.withGap(Time.minutes(5))
处理延迟数据
- allowedLateness(Time.minutes(60))
缩短反馈时间(若用户会话迟迟不结束,反馈时间过长)
- trigger(ContinuousEventTrigger.of(Time.minutes(10)) #每10分钟输出一个结果并覆盖之前的
(4)全局窗口(对全部数据进行统计,使用流方法实现批处理)
内置触发器是NeverTrigger,永远不会触发,需要自定义触发器才有意义
stream.window(GlobalWindows.create()).trigger(...)
4、触发器
继承Trigger类,Trigger抽象类的结构:
boolean canMerge()
void clear(W window, TriggerContext ctx)
TriggerResult onElement(T element, long timestamp, W window, TriggerContext ctx) 每个元素到来时执行
TriggerResult onEventTime(long time, W window, TriggerContext ctx) Timer到期后执行
void onMerge(W window, OnMergeContext ctx)
TriggerResult onProcessingTime(long time, W window, TriggerContext ctx)
5、水印
窗口 + 水印,用于解决乱序问题(并不是解决,而是假定所有正常的事件都只是一定程度内乱序,可以解决此程度内的乱序)
当Watermark在红色区域时,窗口内的元素会计算
(1)基于事件时间处理时,水印是判断所有事件到达的标志,开始计算和输出结果,晚于处理时间但早于此水印时间的事件也可被正确处理。
水印定义最长迟到数据(比当前watermark还早的数据会被丢弃,水印阈值越大,允许的迟到数据越久)
watermark的值不是全局的,但与key无关,有几个并行,就有几个watermark,window的触发条件与最小的watermark有关
水印时间 = 收到的最大事件时间 - 水印阈值
一个操作算子收到多个并行流的输入时,取最小的watermark作为当前算子的watermark
(2)异常情况:如果水印迟到得太久(可能是maxOrderness设置太大,也可能是后序事件过晚到达),收到结果的速度会变慢,解决方法是在水印到达之前输出近似结果,其实就是后面设置Lateness的方案;如果水印到达得太早(可能是maxOrderness设置太小,也可能是后序事件过早到达),则可能丢失一些前序事件,收到错误结果,解决方法是采用Flink作业监控事件流,学习事件的迟到规律,以此构建水印模型
(3)分配Timestamp和Watermark
timestamp和watermark都是通过从1970年1月1日0时0分0秒到现在的毫秒数来指定的
先后顺序:分配timstamp是按设置的时间间隔定时执行的,即使无数据进来也会执行,这就造成了getCurrentWatermark调用后看上去第一个watermark永远是以0为基准计算显示的 ,但实际并不是按那个算的。第2条的watermark如果是23的话,是不大于window_end 24的,也就不应该触发,而如果是下一条的24则可以触发。AssignerWithPeriodicWatermarks子类是每隔一段时间执行的,这个具体由ExecutionConfig.setAutoWatermarkInterval设置,如果没有设置会几乎没有间隔地调用getCurrentWatermark方法。之所以会出现-10000时因为你没有数据进入窗口,当然一直都是-10000,但是getCurrentWatermark方法不是在执行extractTimestamp后才执行的
直接在数据源生成(推荐,数据生成时即分配timestamp和watermark)
实现SourceFuntion接口的run方法,并调用如下方法:
- 分配timestamp:SourceContext.collectWithTimestamp(...)
- 分配watermark:SourceContext.emitWatermark(new WaterMark(...))
获取流后使用生成器生成新流(使用此种方式,会覆盖源提供的timestamp和watermark,注意一定要在时间窗口之前生成)
stram.assignTimestampsAndWatermarks( AssignerWithPeriodicWatermarks/AssignerWithPunctuatedWatermarks 实现类对象)
定义分配器
AssignerWithPeriodicWatermarks(周期性水印,分配时间戳并定期生成水印)
watermark产生的事件间隔(每n毫秒)是通过ExecutionConfig.setAutoWatermarkInterval(...)来定义的,当getCurrentWatermark()被调用时,若返回的watermark非空且大于上一个watermark,则发射一个新的watermark
- 预定义实现类(使用时重写extractTimestamp):
- AscendingTimestampExtractor 适用于时间戳递增的情况
- BoundedOutOfOrdernessTimestampExtractor 适用于乱序但最大延迟已知的情况
- 自定义实现类(使用时重写getCurrentWatermark、extractTimestamp)
AssignerWithPunctuatedWatermarks(带断点水印)
事件驱动生成水印,每个单独的event都可以产生一个watermark,会有额外计算,过多可能导致性能降低。任何一个event都触发extractTimestamp(...)来为元素分配一个timestamp,然后立即调用该元素上的checkAndGetNextWatermark(...)方法,一旦checkAndGetNextWatermark(...)返回一个非空的watermark并且watermark比前一个watermark大的话,这个新的watermark将会被发送
(4)设定水印后触发window的条件:
- watermark >= window_end(开启多并发后,每个算子接收到的watermark都会进行对齐,取最小的watermark作为最终的watermark并往下一个算子发送)
- 在[window_begin, window_end)中有数据存在
(5)不足之处
无法应对迟到数据,如果一个窗口已经被触发了,即使满足上述条件也不会第二次触发窗口。水印被发射到下一个算子前已默认比水印更早的数据已经全部处理了
6、allowedLateness
主要用于解决迟到问题,给迟到数据第二次或多次触发window的机会,可对无法触发window的迟到数据单独处理
默认情况下,watermark超过end-of-window后,将忽略之后到达的符合window的数据
在Watermark < 窗口结束时间 + Lateness时,仍会继续等待窗口内的元素参与窗口计算,计算时要注意状态值的重复,直到Watermark >= 窗口结束时间 + Lateness 时清空缓存
要注意再次触发窗口时,UDF中的状态值的处理,要考虑state在计算时的去重问题
(1)
- 对于trigger是默认的EventTimeTrigger的情况,allowedLateness会再次触发窗口的计算,而之前触发的数据,会buffer起来,直到watermark超过end-of-window + allowedLateness的时间,窗口的数据及元数据信息才会被删除。再次计算就是DataFlow模型中的Accumulating的情况。
- 对于sessionWindow情况,当late element在allowedLateness范围之内到达时,可能会引起窗口的merge,这样,之前窗口的数据会在新窗口中累加计算,这就是DataFlow模型中的AccumulatingAndRetracting的情况。
(2)触发条件
- watermark < window_end + allowedLateness
- 在[window_begin, window_end)中有late数据存在
7、定时器Timer
Flink Streaming API提供的用于感知并利用处理时间/事件时间变化的机制
(1)在KeyedProcessFunction实现类里定义定时器为例:
重写processElement(),对每个输入元素注册定时器
重写onTimer(),定时器触发时执行的逻辑
根据时间特征的不同,具体如下:
处理时间——调用Context.timerService().registerProcessingTimeTimer()注册;onTimer()在系统时间戳达到Timer设定的时间戳时触发。
事件时间——调用Context.timerService().registerEventTimeTimer()注册;onTimer()在Flink内部水印达到或超过Timer设定的时间戳时触发。
(2)EventTimeTrigger使用Timer实现触发时间窗口
@Override
public TriggerResult onElement(Object element, long timestamp, TimeWindow window, TriggerContext ctx) throws Exception {
if (window.maxTimestamp() <= ctx.getCurrentWatermark()) { return TriggerResult.FIRE; }
else { ctx.registerEventTimeTimer(window.maxTimestamp()); return TriggerResult.CONTINUE; }
}
Flink之对时间的处理的更多相关文章
- Flink学习(二)Flink中的时间
摘自Apache Flink官网 最早的streaming 架构是storm的lambda架构 分为三个layer batch layer serving layer speed layer 一.在s ...
- 「Flink」Flink中的时间类型
Flink中的时间类型和窗口是非常重要概念,是学习Flink必须要掌握的两个知识点. Flink中的时间类型 时间类型介绍 Flink流式处理中支持不同类型的时间.分为以下几种: 处理时间 Flink ...
- Flink基础:时间和水印
往期推荐: Flink基础:入门介绍 Flink基础:DataStream API Flink基础:实时处理管道与ETL Flink深入浅出:资源管理 Flink深入浅出:部署模式 Flink深入 ...
- 第08讲:Flink 窗口、时间和水印
Flink系列文章 第01讲:Flink 的应用场景和架构模型 第02讲:Flink 入门程序 WordCount 和 SQL 实现 第03讲:Flink 的编程模型与其他框架比较 第04讲:Flin ...
- 「Flink」事件时间与水印
我们先来以滚动时间窗口为例,来看一下窗口的几个时间参数与Flink流处理系统时间特性的关系. 获取窗口开始时间Flink源代码 获取窗口的开始时间为以下代码: org.apache.flink.str ...
- Flink流处理的时间窗口
Flink流处理的时间窗口 对于流处理系统来说,流入的消息是无限的,所以对于聚合或是连接等操作,流处理系统需要对流入的消息进行分段,然后基于每一段数据进行聚合或是连接等操作. 消息的分段即称为窗口,流 ...
- Flink Streaming基于滚动窗口的事件时间分析
使用flink-1.9.0进行的测试,在不同的并行度下,Flink对事件时间的处理逻辑不同.包括1.1在并行度为1的本地模式分析和1.2在多并行度的本地模式分析两部分.通过理论结合源码进行验证,得到具 ...
- Flink的时间类型和watermark机制
一FlinkTime类型 有3类时间,分别是数据本身的产生时间.进入Flink系统的时间和被处理的时间,在Flink系统中的数据可以有三种时间属性: Event Time 是每条数据在其生产设备上发生 ...
- Flink架构(三)- 事件-时间(Event-Time)处理
3. 事件-时间(Event-Time)处理 在“时间语义”中,我们强调了在流处理应用中时间语义的重要性,并解释了处理时间与事件时间的不同点.处理时间较好理解,因为它基于本地机器的时间,它产生的是有点 ...
随机推荐
- 使用python解线性矩阵方程(numpy中的matrix类)
这学期有一门运筹学,讲的两大块儿:线性优化和非线性优化问题.在非线性优化问题这里涉及到拉格朗日乘子法,经常要算一些非常变态的线性方程,于是我就想用python求解线性方程.查阅资料的过程中找到了一个极 ...
- Windows 10 WSL 2.0安装并运行Docker
在Windows 10 2004版本,微软更新WSL到了2.0,WSL 2.0已经拥有了完整的Linux内核!今天来测试一下,是否可以安装docker! 一.开启WSL 以管理员运行Powershe ...
- 经典卷积神经网络算法(5):ResNet
.caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...
- linux 系统文件目录颜色及特殊权限对应的颜色
什么决定文件目录的颜色和背景? 颜色 说明 栗子 权限 白色 表示普通文件 蓝色 表示目录 绿色 表示可执行文件 浅蓝色 链接文件 黄色 表示设备文件 红色 表示压缩文件 红色闪烁 ...
- disruptor架构四 多生产者多消费者执行
1.首先介绍下那个时候使用RingBuffer,那个时候使用disruptor ringBuffer比较适合场景比较简单的业务,disruptor比较适合场景较为复杂的业务,很多复杂的结果必须使用di ...
- Vue组件篇——Vue3.0中使用高德地图
VUE-CLI 3.0 中配置高德地图 在项目开发中,地图组件 1.首先,需要注册高德开放平台的账号,并在[应用管理]页面[创建新应用],为应用添加Key值 高德开放平台:https://lbs.am ...
- C#数据结构与算法系列(十九):选择排序算法(SelectSort)
1.介绍 选择排序算法属于内部排序算法,是从欲排序的数据中,按指定的规则选出某一元素,再依规定交换位置达到排序的目的 时间复杂度:O(n^2) 双层for 2.思想 选择排序(select sorti ...
- 【转载】张一鸣:为什么 BAT 挖不走我们的人才?
很多企业失败的时候,总说是政策的变化.市场的变化.消费者需求的变化.技术发展的变化等等,导致了失败,其实这都是瞎说,归根结底还是人的原因,都是因为你招的人不行.可见,人才对于一个企业的重要性. 互联网 ...
- Validate日期校验
public class Validate { private static Regex RegNumber = new Regex("^[0-9]+$"); private st ...
- hibernate快速入门示例
hibernate概述 hibernate是一个java的全自动ORM框架,它可以自动生成SQL语句.自动建表.自动执行,使用者可以不使用SQL完成数据的CRUD操作,同时它也是基于JPA规则的一种实 ...