(9)Flink-Time

目录

1、三种Time

1.1、比较

 1.2、根据业务选择最合适的时间

1.3、设置time类型

2、时间戳和水位线背后的机制

2.1 Watermarks是干啥的

2.2有序流中Watermarks

2.3乱序流中Watermarks

2.4并行流中的Watermarks

3.生成Timestamp和Watermark

3.1 Timestamp /Watermark两种生成方式

3.1.1 方式一、直接在source function中生成

3.1.2方式二、 timestamp assigner / watermark generator

3.2、两种Watermark 

3.2.1、Periodic Watermark

3.2.2、Puncuated Watermark

4、预定义Timestamp Extractors / Watermark Emitters 

4.1Assigners with ascending timestamps

4.2允许固定延迟的Assigner

4.3延迟数据处理

 


如果下面的读不懂可以先读白话解析

1、三种Time

DataStream有大量基于time的operator,windows操作只是其中一种。

Flink支持三种time:

1.EventTime

2.IngestTime

3.ProcessingTime

1.1、比较

EventTime

1.事件生成时的时间,在进入Flink之前就已经存在,可以从event的字段中抽取。

2.必须指定watermarks(水位线)的生成方式。

3.优势:确定性,乱序、延时、或者数据重放等情况,都能给出正确的结果

4.弱点:处理无序事件时性能和延迟受到影响

IngestTime

1.事件进入flink的时间,即在source里获取的当前系统的时间,后续操作统一使用该时间。

2.不需要指定watermarks的生成方式(自动生成)

3.弱点:不能处理无序事件和延迟数据

 

ProcessingTime

1.执行操作的机器的当前系统时间(每个算子都不一样)

2.不需要流和机器之间的协调

3.优势:最佳的性能和最低的延迟

4.弱点:不确定性 ,容易受到各种因素影像(event产生的速度、到达flink的速度、在算子之间传输速度等),压根就不管顺序和延迟

 

比较

性能: ProcessingTime> IngestTime> EventTime

延迟: ProcessingTime< IngestTime< EventTime

确定性: EventTime> IngestTime> ProcessingTime

 1.2、根据业务选择最合适的时间

Hadoop的日志进入Flink的时间为2018-12-23 17:43:46,666(Ingest Time),

在进入window操作时那台机器的系统时间是2018-12-23 17:43:47,120(Processing Time),日志的具体内容是:

      (Event Time)2018-12-23 16:37:15,624 INFO org.apache.hadoop.yarn.client.ConfiguredRMFailoverProxyProvider - Failing over to rm2

要统计每个5min内的日志error个数,哪个时间是最有意义的? 最佳选择就是【event time】。一般都需要使用event time,除非由于特殊情况只能用另外两种时间来代替。

1.3、设置time类型

设置时间特性

final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); 
env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);

不设置Time 类型,默认是processingTime。

如果使用EventTime则需要在source之后明确指定Timestamp Assigner & Watermark Generator(见后面小节)。

2、时间戳和水位线背后的机制

2.1 Watermarks是干啥的

out-of-order/late element

实时系统中,由于各种原因造成的延时,造成某些消息发到flink的时间延时于事件产生的时间。如果基于【event time】构建window,但是对于late element,我们又不能无限期的等下去,必须要有个机制来保证一个特定的时间后,必须触发window去进行计算了。这个特别的机制,就是watermark。

此处引用一些其他网站的知识解释watermarks:

Window:Window是处理无界流的关键,Windows将流拆分为一个个有限大小的buckets,可以可以在每一个buckets中进行计算

start_time,end_time:当Window时时间窗口的时候,每个window都会有一个开始时间和结束时间(前开后闭),这个时间是系统时间

event-time: 事件发生时间,是事件发生所在设备的当地时间,比如一个点击事件的时间发生时间,是用户点击操作所在的手机或电脑的时间

Watermarks:可以把他理解为一个水位线,这个Watermarks在不断的变化,一旦Watermarks大于了某个window的end_time,就会触发此window的计算,Watermarks就是用来触发window计算的。

-------------------------------------------------------------------------------------------------

watermark是flink为了处理eventTime窗口计算提出的一种机制,本质上也是一种时间戳,由flink souce或者自定义的watermark生成器按照需求定期或者按条件生成一种系统event,与普通数据流event一样流转到对应的下游operations,接收到watermark数据的operator以此不断调整自己管理的window event time clock。

其实是翻译的有问题,实际上应该翻译为水位线。接受的数据就相当于浮在水面的物体,水位线的高度只会升高不会降低,每当一个新数据进来时,会重新计算水位线时间,但是计算结果小于当前水位线时间,则不会更新现有的水位线。 当水位线到达窗口触发时间时才会触发窗口的计算。
watermark的意义在于数据无序传递的时候有一定容错率,如果晚来的数据在容错范围之内,会当做正常传递来处理。

Watermarks(水位线)就是来处理这种问题的机制

1.参考google的DataFlow。

2.是event time处理进度的标志。

3.表示比watermark更早(更老)的事件都已经到达(没有比水位线更低的数据 )。

4.基于watermark来进行窗口触发计算的判断。

2.2有序流中Watermarks

在某些情况下,基于Event Time的数据流是有续的(相对event time)。在有序流中,watermark就是一个简单的周期性标记。

2.3乱序流中Watermarks

 

上图可以类比银行或者医院的排号来理解。

2.4并行流中的Watermarks

通常情况下, watermark在source函数中生成,但是也可以在source后任何阶段,如果指定多次 watermark,后面指定的 watermark会覆盖前面的值。 source的每个sub task独立生成水印。

watermark通过operator时会推进operators处的当前event time,同时operators会为下游生成一个新的watermark。

多输入operator(union、 keyBy、 partition)的当前event time是其输入流event time的最小值。

 

3.生成Timestamp和Watermark

3.1 Timestamp /Watermark两种生成方式

只有基于EventTime的流处理程序需要指定Timestamp和Watermarks的生成方式。

指定时间特性为Event Time(前面讲过)。

final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

分配timestamp和生成Watermarks两种方式:

声明时间特性为Event Time后,Flink需要知道每个event的timestamp(一般从event的某个字段去抽取),Flink还需要知道目前event time的进度也就是Watermarks(一般伴随着Event Time一起指定生成方式,二者息息相关)

方式1:直接在source function中生成

方式2:timestamp assigner / watermark generator

注意:timestamp和watermark都是采用毫秒(从java的1970-01-01T00:00:00Z时间作为起始)。

声明:event、element、record都是一个意思。

3.1.1 方式一、直接在source function中生成

自定义source实现SourceFunction接口或者继承RichParallelSourceFunction。

 

3.1.2方式二、 timestamp assigner / watermark generator

通过assignTimestampsAndWatermarks方法指定timestamp assigner / watermark generator

一般在datasource后调用assignTimestampsAndWatermarks,也可以在第一个基于event time的operator之前指定(例如window operator)。

案例参考1:生成EventTime和Watermark

对于这个案例我的理解就是:经过上面代码(结合Window)的处理乱序的数据变为有序了。 

 

参考案例2Flink流计算编程--watermark(水位线)简介


另一个案例:使用Kafka Connector作为source时,在source内部assignTimestampsAndWatermarks。

3.2、两种Watermark 

  • Periodic(周期性) Watermarks

1.基于Timer

2.ExecutionConfig.setAutoWatermarkInterval(msec) (默认是 200ms, 设置watermarker 发送的周期)。

3.实现AssignerWithPeriodicWatermarks 接口。

  • Puncuated(间断的) WaterMarks

1.基于某些事件触发watermark 的生成和发送(由用户代码实现,例如遇到特殊元素) 。

2.实现AssignerWithPeriodicWatermarks 接口。

3.2.1、Periodic Watermark

周期性调用getCurrentWatermark,如果获取的Watermark不等于null且比上一个最新的Watermark大就向下游发射。

3.2.2、Puncuated Watermark

间断性调用getCurrentWatermark,它会根据一个条件发送watermark,这个条件可以自己去定义。

4、预定义Timestamp Extractors / Watermark Emitters 

4.1Assigners with ascending timestamps

适用于event时间戳单调递增的场景,数据没有太多延时。

4.2允许固定延迟的Assigner

适用于预先知道最大延迟的场景(例如最多比之前的元素延迟3000ms)。

4.3延迟数据处理

延时数据处理一般有两种处理方式:

方式一:allowedLateness(),设定最大延迟时间,触发被延迟,不宜设置太长。

方式二: sideOutputTag ,提供了延迟数据获取的一种方式,这样就不会丢弃数据了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值