flink----12 wartermark 案例,接上一节

本文介绍了Flink中watermark结合window机制处理乱序数据的方法。包括测试乱序数据时window的触发条件,还阐述了延迟数据的三种处理方案:丢弃、指定允许延迟时间、收集迟到数据。此外,说明了多并行度下watermark对齐问题,以及Flink设置最大乱序时间的要点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一节的案例我们得到了触发window的条件

watermark+window 处理乱序数据

我们上面的测试,数据都是按照时间顺序递增的,现在,我们输入一些乱序的(late)数据,

看看 watermark 结合 window 机制,是如何处理乱序的。

nc -l 9000

0001,1538359882000

0001,1538359886000

0001,1538359892000

0001,1538359893000

0001,1538359894000

0001,1538359896000

0001,1538359899000

0001,1538359891000

Key

Event Time

CurrentMaxTim eStamp

WaterMark

window_start_ time

window_end_t ime

0001

1538359882000
1538359882000
1538359872000
  

2018-10-01 10:11:22.000

2018-10-01 10:11:22.000

2018-10-01 10:11:12.000

  

0001

1538359886000
1538359886000
1538359876000
  

2018-10-01 10:11:26.000

2018-10-01 10:11:26.000

2018-10-01 10:11:16.000

  

0001

1538359892000
1538359892000
1538359882000
  

2018-10-01 10:11:32.000

2018-10-01 10:11:32.000

2018-10-01 10:11:22.000

  

0001

1538359893000
1538359893000
1538359883000
  

2018-10-01 10:11:33.000

2018-10-01 10:11:33.000

2018-10-01 10:11:23.000

  

0001

1538359894000
1538359894000
1538359884000
  

2018-10-01 10:11:34.000

2018-10-01 10:11:34.000

2018-10-01 10:11:24.000

[10:11:21.000

10:11:24.000)

0001

1538359896000
1538359896000
1538359886000
  

2018-10-01 10:11:36.000

2018-10-01 10:11:36.000

2018-10-01 10:11:26.000

  

0001

1538359897000
1538359897000
1538359887000
  

2018-10-01 10:11:37.000

2018-10-01 10:11:37.000

2018-10-01 10:11:27.000

[10:11:24.000

10:11:27.000)

0001

1538359899000
1538359899000
1538359889000
  

2018-10-01 10:11:39.000

2018-10-01 10:11:39.000

2018-10-01 10:11:29.000

  

0001

1538359891000
1538359899000
1538359889000
  

2018-10-01 10:11:31.000

2018-10-01 10:11:39.000

2018-10-01 10:11:29.000

  

 可以看到,虽然我们输入了一个 10:11:31 的数据,但是 currentMaxTimestamp 和 watermark 都没变。此时,按照我们上面提到的公式:

watermark 时间(10:11:29) < window_end_time(10:11:33),因此不能触发 window。

那如果我们再次输入一条 10:11:43 的数据,此时 watermark 时间会升高到 10:11:33,这时的 window 一定就会触发了,我们试一试:
输入:

nc -l 9000

0001,1538359882000

0001,1538359886000

0001,1538359892000

0001,1538359893000

0001,1538359894000

0001,1538359896000

0001,1538359899000

0001,1538359891000

0001,1538359893000

汇总信息就不写了

 

 

关于late element(延迟数据)的处理

延迟数据三种处理方案

丢弃(默认)

我们输入一个乱序很多的(其实只要 Event Time < watermark 时间)数据来测试下: 输入:

nc -l 9000

0001,1538359890000

0001,1538359903000

注意:此时 watermark 是 2018-10-01 10:11:33.000 下面我们再输入几个 eventtime 小于 watermark 的时间

在输入

nc -l 9000

0001,1538359890000

0001,1538359903000

0001,1538359890000

0001,1538359891000

0001,1538359892000

注意:此时并没有触发 window。因为输入的数据所在的窗口已经执行过了,flink 默认对这 些迟到的数据的处理方案就是丢弃。

 

 

allowedLateness 指定允许数据延迟的时间

在某些情况下,我们希望对迟到的数据再提供一个宽容的时间。
Flink 提供了 allowedLateness 方法可以实现对迟到的数据设置一个延迟时间,在指定延迟时 间内到达的数据还是可以触发 window 执行的。

下面我们来验证一下:
输入:【输入两行内容】

nc -l 9000

0001,1538359890000

0001,1538359903000

 

正常触发 window,没什么问题。 汇总:

Key

Event Time

CurrentMaxTim eStamp

WaterMark

window_start_ time

window_end_t ime

0001

1538359890000
1538359890000
1538359880000
  

2018-10-01 10:11:30.000

2018-10-01 10:11:30.000

2018-10-01 10:11:20.000

  

0001

1538359903000
1538359903000
1538359893000
  

2018-10-01 10:11:43.000

2018-10-01 10:11:43.000

2018-10-01 10:11:33.000

[10:11:33.000

10:11:33.000)

 此时 watermark 是 2018-10-01 10:11:33.000 那么现在我们输入几条 eventtime<watermark 的数据验证一下效果

nc -l 9000

0001,1538359890000

0001,1538359903000

0001,1538359890000

0001,1538359891000

0001,1538359892000

在这里看到每条数据都触发了 window 执行。 汇总:

Key

Event Time

CurrentMaxTim eStamp

WaterMark

window_start_ time

window_end_t ime

0001

1538359890000
1538359890000
1538359880000
  

2018-10-01 10:11:30.000

2018-10-01 10:11:30.000

2018-10-01 10:11:20.000

  

0001

1538359903000
1538359903000
1538359893000
  

2018-10-01 10:11:43.000

2018-10-01 10:11:43.000

2018-10-01 10:11:33.000

[10:11:33.000

10:11:33.000)

0001

1538359890000
1538359903000
1538359893000
  

2018-10-01 10:11:30.000

2018-10-01 10:11:43.000

2018-10-01 10:11:33.000

[10:11:33.000

10:11:33.000)

0001

1538359891000
1538359903000
1538359893000
  

2018-10-01 10:11:31.000

2018-10-01 10:11:43.000

2018-10-01 10:11:33.000

[10:11:33.000

10:11:33.000)

0001

1538359892000
1538359903000
1538359893000
  

2018-10-01 10:11:32.000

2018-10-01 10:11:43.000

2018-10-01 10:11:33.000

[10:11:33.000

10:11:33.000)

我们再输入一条数据,把 water 调整到 10:11:34 输入:

 

nc -l 9000

0001,1538359890000

0001,1538359903000

0001,1538359890000

0001,1538359891000

0001,1538359892000

0001,1538359894000

此时,把 water 上升到了 10:11:34,我们再输入几条 eventtime<watermark 的数据验证一下

nc -l 9000

0001,1538359890000

0001,1538359903000

0001,1538359890000

0001,1538359891000

0001,1538359892000

0001,1538359894000

0001,1538359890000

0001,1538359891000

0001,1538359892000

发现输入的三行数据都触发了 window 的执行。

我们再输入一条数据,把 water 调整到 10:11:35

nc -l 9000

0001,1538359890000

0001,1538359903000

0001,1538359890000

0001,1538359891000

0001,1538359892000

0001,1538359894000

0001,1538359890000

0001,1538359891000

0001,1538359895000

此时,watermark 上升到了 10:11:35
我们再输入几条 eventtime<watermark 的数据验证一下效果

nc -l 9000

0001,1538359890000

0001,1538359903000

0001,1538359890000

0001,1538359891000

0001,1538359892000

0001,1538359894000

0001,1538359890000

0001,1538359891000

0001,1538359895000

0001,1538359890000

0001,1538359891000

0001,1538359892000

发现这几条数据都没有触发 window。

分析:
当 watemark 等于 10:11:33 的时候,正好是 window_end_time,所以会触发[10:11:30~10:11:33) 的 window 执行。
当窗口执行过后,我们输入[10:11:30~10:11:33) window 内的数据会发现 window 是可以被触 发的。
当 watemark 提升到 10:11:34 的时候,我们输入[10:11:30~10:11:33)window 内的数据会发现 window 也是可以被触发的。
当 watemark 提升到 10:11:35 的时候,我们输入[10:11:30~10:11:33)window 内的数据会发现 window 不会被触发了。

由于我们在前面设置了 allowedLateness(Time.seconds(2)),可以允许延迟在 2s 内的数据继续 触发 window 执行。

所以当 watermark 是 10:11:34 的时候可以触发 window,但是 10:11:35 的时候就不行了。

总结:
对于此窗口而言,允许 2 秒的迟到数据,即第一次触发是在 watermark >=window_end_time 时
第二次(或多次)触发的条件是 watermark < window_end_time + allowedLateness 时间内, 这个窗口有 late 数据到达时。

解释:
当 watermark 等于 10:11:34 的时候,我们输入 eventtime 为 10:11:30、10:11:31、10:11:32 的 数据的时候,是可以触发的,因为这些数据的 window_end_time 都是 10:11:33,也就是 10:11:34<10:11:33+2 为 true。

但是当 watermark 等于 10:11:35 的时候,我们再输入 eventtime 为 10:11:30、10:11:31、10:11:32 的数据的时候,这些数据的 window_end_time 都是 10:11:33,此时,10:11:35<10:11:33+2 为 false 了。所以最终这些数据迟到的时间太久了,就不会再触发 window 执行了。

 

 

第三种策略:

sideOutputLateData 收集迟到的数据

通过 sideOutputLateData 可以把迟到的数据统一收集,统一存储,方便后期排查问题

此时,针对这几条迟到的数据,都通过 sideOutputLateData 保存到了 outputTag 中。

 

 

多并行度情况下的wartermark

改一下代码

输入如下几行内容:

0001,1538359882000

0001,1538359886000

0001,1538359892000

0001,1538359892000

0001,1538359894000

0001,1538359896000

0001,1538359897000

会发现 window 没有被触发。
因为此时,这 7 条数据都是被不同的线程处理的。每个线程都有一个 watermark。

因为在多并行度的情况下,watermark 对齐会取所有 channel 最小的 watermark 但是我们现在默认有 8 个并行度,这 7 条数据都被不同的线程所处理,到现在还没获取到最 小的 watermark,所以 window 无法被触发执行。

下面我们来验证一下,把代码中的并行度调整为 2.

输入如下几行内容:

0001,1538359890000

0001,1538359903000

0001,1538359908000

此时会发现,当第三条数据输入完以后,[10:11:30,10:11:33)这个 window 被触发了。 前两条数据输入之后,获取到的最小 watermark 是 10:11:20,这个时候对应的 window 中没 有数据。
第三条数据输入之后,获取到的最小 watermark 是 10:11:33,这个时候对应的窗口就是 [10:11:30,10:11:33)。所以就触发了。

 

Flink应该如何设置最大乱序时间

这个要结合自己的业务以及数据情况去设置。如果maxOutOfOrderness设置的太小,而自身数据发送时由于网络等原因导致乱序或者late太多,那么最终的结果就是会有很多单条的数据在window中被触发,数据的正确性影响太大

对于严重乱序的数据,需要严格统计数据最大延迟时间,才能保证计算的数据准确,延时设置太小会影响数据准确性,延时设置太大不仅影响数据的实时性,更加会加重Flink作业的负担,不是对eventTime要求特别严格的数据,尽量不要采用eventTime方式来处理,会有丢数据的风险。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值