Flink随数据流动的四种StreamElement简述

Flink为了完成不同的任务,在DataStream中流动的不止是我们的业务数据StreamRecord,还有其余三种标记,分别是Watermark,StreamStatus,LatencyMarker。这四个类继承自StreamElement。

(注:有些人可能有疑惑,checkpoint barrier不是插入了数据流中吗?是的,checkpoint barrier也是随着数据流动,但是它不属于StreamElement的体系,Flink对其进行单独处理)

下面分别对四种类型进行介绍

StreamRecord

StreamRecord就是业务数据的一个包装类,在其value属性中存储从数据源中获取的数据。同时为这条数据附加了timestamp和hasTimestamp属性。

Watermark

watermark大家都比较熟悉了,在使用事件时间语义时,watermark起到推进时间进度,触发窗口计算的作用。

当某个watermark流动到某个operator时,表示小于watermark的数据都已经到达,可以触发窗口计算,触发定时器。也可以根据watermark处理迟到数据。如果出现watermark的值为Long.MAX_VALUE时,代表对应的数据源关闭了。

StreamStatus

当我们的程序中有多条输入流时,由于watermark更新时会选择其中的最小值,如果有一条输入流没有数据了,水印也就不会更新,那么下游就无法触发计算,为了解决这个问题,引入了StreamStatus。

StreamStatus用来表示某一条数据流的状态:

StreamStatus.ACTIVE_STATUS 表示当前数据流处于活动状态

StreamStatus.IDLE_STATUS 表示当前输入流处于闲置状态

当一条输入流处理IDLE状态时,其不会再向下游发送数据和水印,下游在进行水印更新的时候,会忽略掉这条闲置流。这样就不会影响正常的数据处理逻辑。下游可以继续工作。

当闲置的数据流有了新的数据,其就会转变为ACTIVE_STATUS。因为水印是不能倒退的,所以只有这条流的watermark大于等于上次触发窗口计算的watermark时,才会参与本次的最小水印选择。

LatencyMarker

Flink为了监控数据处理延迟,在source端周期性插入LatencyMarker,其内部的markedTime属性表示了创建的时间。随着数据的流动,每当一个operator收到LatencyMarker时,就会用当前时间 - marker.getMarkedTime() 将结果报告给指标收集系统,然后把这个LatencyMarker向下游转发。

要注意使用LatencyMarker探测出的延迟并不是端到端延迟,因为其转发没有经过用户逻辑。LatencyMarker会直接emit。由于业务数据处理和LatencyMarker的处理是同步的,随着数据流的流动,其结果和端到端延迟近似。

你可能感兴趣的:(Flink,flink,数据流,StreamElement,StreamStatus)