flink watermark原理总结

flink watermark原理总结

flink如何处理乱序?

通过窗口对input按照eventTime进行聚合,使得大体按照event time 发生的顺序去处理数据,同时利用watermark来触发窗口。(watermark + window机制)

watermark原理及简介?

Watermark是Flink为了处理EventTime时间类型(其他时间类型不考虑乱序问题)的窗口计算提出的一种机制,本质上也是一种时间戳。Watermark是用于处理乱序事件的,而正确的处理乱序事件,通常用watermark机制结合window来实现。

当operator通过基于Event Time的时间窗口来处理数据时,它必须在确定所有属于该时间窗口的消息全部流入此操作符后,才能开始处理数据。但是由于消息可能是乱序的,所以operator无法直接确认何时所有属于该时间窗口的消息全部流入此操作符。WaterMark包含一个时间戳,Flink使用WaterMark标记所有小于该时间戳的消息都已流入,Flink的数据源在确认所有小于某个时间戳的消息都已输出到Flink流处理系统后,会生成一个包含该时间戳的WaterMark,插入到消息流中输出到Flink流处理系统中,Flink operator算子按照时间窗口缓存所有流入的消息,当操作符处理到WaterMark时,它对所有小于该WaterMark时间戳的时间窗口的数据进行处理并发送到下一个操作符节点,然后也将WaterMark发送到下一个操作符节点。

watermark有什么用?

流处理的过程中,从事件产生,到流经source,operator,中间是有一个过程和时间的,虽然大部分情况下,流到operator的数据都是按照事件产生的时间顺序来的,但是由于网络,背压等原因,导致乱序的产生。(out-of-order或者说late element)

对于late element,我们不能无限期的等下去,必须有一个机制保证在特定的时间后,必须触发window去计算,这个特别的机制就是watermark。

watermark如何产生?

通常,在接收到source的数据后,会立刻生成watermark;但是,也可以在source之后,应用简单的map、filter再生成watermark。

生成watermark的方式有两种:

1.Periodic Watermarks
Periodic Watermarks,周期性的产生watermark,即每隔一定时间间隔或者达到一定的记录条数,产生一个watermark。

而在实际的生产中,periodic方式必须结合时间和记录数两个维度,否则,在极端情况下容易产生很大的延时。
2.Punctuated Watermarks
Punctuated Watermarks,数据流中每一个递增的event time 都会产生一个watermark。
在实际的生产中,punctuated 方式在TPS很高的场景下会产生大量的watermark,
在一定程度上对下游算子造成压力,所以只有在实时性要求非常高的场景才会选择punctuated方式。

代码实现:

注意:为什么Watermark=currentMaxTimestamp - maxLateTime?

假设不考虑延迟,watermark=currentMaxTimeStamp,随着水位线的上升,当水位线(即当前最大时间)超过endtime时,所有的数据已经全部进入该窗口了。

继续考虑存在延迟的情况,为了使得延时了maxLateTime的数据全部进入窗口,预先让水位线下降maxLateTime,在这种情况下,当水位线依然超过endtime时,表明在允许延迟的情况下,所有数据全部进入该窗口了。

如果顺序,只需要最新的event time >=windowEndTime,窗口就会触发。

如果乱序,由于要等 maxLateTime,所以最新的event time - maxLateTime >=windowEndTime时,窗口触发。这里取其次,只要currentMaxTimestamp- maxLateTime>=windowEndTime,窗口就会触发。

/**
 *flink 1.7
 hello,2019-09-17 11:34:05.890
 hello,2019-09-17 11:34:07.890
 hello,2019-09-17 11:34:13.890
 hello,2019-09-17 11:34:08.890
 hello,2019-09-17 11:34:16.890
 hello,2019-09-17 11:34:19.890
 hello,2019-09-17 11:34:21.890
 */

public class WaterMarkTest {
   

    public static void main(String[] args) throws ParseException {
   

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

        env.setParallelism(1);
        //设置多久查看一下当前的水位线... 默认200ms
//        env.getConfig().setAutoWatermarkInterval(10000);
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值