[Flink] Flink的waterMark的通俗理解

导读

Flink 为实时计算提供了三种时间,即事件时间(event time)、摄入时间(ingestion time)和处理时间(processing time)。

遇到的问题:

假设在一个5秒的Tumble窗口,有一个EventTime是 11秒的数据,在第16秒时候到来了。图示第11秒的数据,在16秒到来了,如下图:该如何处理迟到数据

undefined

什么是Watermark

Watermark的关键点:

  • 目的:处理EventTime 窗口计算
  • 本质:时间戳
  • 生成方式:Punctuated和Periodic(常用)
  • 特性:单调递增

Watermark的产生方式

  • Punctuated

    数据流中每一个递增的EventTime都会产生一个Watermark。

  • Periodic(推荐)

    周期性的(一定时间间隔或者达到一定的记录条数)产生一个Watermark。

Watermark解决的问题

上面的问题在于如何将迟来的EventTime 位11的元素正确处理?

当Watermark的时间戳等于Event中携带的EventTime时候,上面场景(Watermark=EventTime)的计算结果如下:

undefined

如果想正确处理迟来的数据可以定义Watermark生成策略为 Watermark = EventTime -5s, 如下:

undefined

WaterMark的例子

设置WaterMark步骤:

1.设置StreamTime Characteristic为Event Time,即设置流式时间窗口(也可以称为流式时间特性)

2.创建的DataStreamSource调用assignTimestampsAndWatermarks方法,并设置WaterMark种类:AssignerWithPeriodicWatermarks / AssignerWithPunctuatedWatermarks

或者 实现AssignerWithPeriodicWatermarks接口 / 实现AssignerWithPunctuatedWatermarks接口

3.重写getCurrentWatermark与extractTimestamp方法

getCurrentWatermark方法:获取当前的水位线

extractTimestamp方法:提取数据流中的时间戳(必须显式的指定数据中的Event Time)

实例

通过一段程序,实践一下WaterMark的设定以及WaterMark的工作方式

数据示例

key + 时间戳

hello,1553503210000 

程序说明

1.使用Socket模拟接收数据

2.设置WaterMark

设置的逻辑:在第一条数据进来时,设置WaterMark为0,指定第一条数据的时间戳后,获取该时间戳与当前 WaterMark的最大值,并将最大值设置为下一条数据的WaterMark,以此类推

3.进行map基础转换,将String转换为Tuple2<String,String>

4.根据Key分组

5.使用滚动Event Time窗口,将5秒内的同组数据,进行Fold拼接输出

代码如下:

package waterMark;

import org.apache.flink.api.common.functions.FoldFunction;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.TimeCharacteristic;
imp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值