pig2 发表于 2019-3-15 13:23:13

Flink难点解析1:揭开Watermark的神秘面纱【机制篇】

本帖最后由 pig2 于 2019-3-15 13:23 编辑

问题导读

1.什么是水位线?
2.水位线的作用是什么?
3.水位线的本质是什么?
4.水位线是为了解决什么问题?


刚接触Flink,可能你听说过“水印”或则“水位线”,但是技术领域为何会出现非技术词汇,到底什么是水位线,这两个陌生的词汇,给Flink蒙上了一层神秘的面纱。

这里我们就为大家揭开Watermark的神秘面纱。

回到Flink场景中来,Flink被称为终极流式框架,它是真正的流式处理,认为批处理是流处理的特殊情况,整因为这样,Flink统一了流处理和批处理。

我们这里的水位线,说的就是流处理事件中一个概念或则说流处理过程中遇到问题的解决方案。
在说水位线之前,为了照顾新手,我们首先需要明白什么是流处理?

所谓的流处理,最本质的是在处理数据的时候,是接受一条处理一条数据。而批处理,则是累积数据到一定程度在处理。这是他们本质的区别。

流数据异常该怎么办:

上面我们明白了什么是流处理,先不要着急去想什么Watermark,假如我们自己写一个流式框架。我们该如何处理消息。如下,我们看到消息按照顺序一个个发送,接受后按照顺序处理,这是没有什么问题的。



然而在来看下面情况:
消息不在是按照顺序发送,产生了乱序,这时候该怎么处理?
http://www.aboutyun.com/data/attachment/forum/201810/22/095247oae2zeq7liiylit7.png
如果你看到这里,相信很多人可以猜出来了,水位线-Watermark是其中的解决方案之一。

看到这里其实可能还是懵逼状态,水位线怎么能解决这个乱序。

为了更好地明白下面讲的内容,补充下Flink的一些基本知识。
1.Flink 窗口(Window)
对于Flink如果来一条消息计算一条,这样是可以的,但是这样计算是非常频繁而且消耗资源,如果想做一些统计这是不可能的。所以对于Spark和Flink都产生了窗口计算。对于窗口感兴趣可参考Flink实时性、容错机制、窗口等介绍

2.事件时间
我们知道一个事件发生了,肯定是有时间的,这个时间,在Flink中被称之为事件时间,也就是Event Time。当然还有其它时间,如感兴趣可参考Flink系统学习11:【Flink1.7】事件时间、处理时间、提取时间有什么区别
上面两个概念明白了,我们就要讲:

watermark有什么用?
watermark是用于处理乱序事件的,而正确的处理乱序事件,通常用watermark机制结合window来实现。

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

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


如何使用Watermarks处理乱序的数据流?
什么是乱序呢?如上面图示,可以理解为数据到达的顺序和他的event-time(事件发生时间)排序不一致。导致这的原因有很多,比如延迟,消息积压,重试等等

因为Watermarks是用来触发window窗口计算的,我们可以根据事件的event-time,计算出Watermarks,并且设置一些延迟,给迟到的数据一些机会,也就是说正常来讲,对于迟到的数据,我只等你一段时间,再不来就没有机会了。

这里我们需要稍微解释下:窗口的触发机制,比如滚动窗口,或则滑动窗口等,他们都是有自己的触发机制的,比如每隔5秒,窗口就会计算一次,也就是说,每隔5秒窗口就会触发一次。如对窗口计算不了解或则感兴趣,可参考Flink实时性、容错机制、窗口等介绍。这里不再详述。


我们明白了窗口的触发机制,这里我们添加了水位线,到底是个怎么个情况?我们来看下面
假如我们设置10s的时间窗口(window),那么0~10s,10~20s都是一个窗口,以0~10s为例,0位start-time,10为end-time。假如有4个数据的event-time分别是8(A),12.5(B),9(C),13.5(D),我们设置Watermarks为当前所有到达数据event-time的最大值减去延迟值3.5秒,也就是说对于迟到的数据,我们只等你3.5秒。【这里你可能有个问题,如果超过3.5秒该怎么办,这时候就需要我们对生产环境有一个整体的认识和把握,数据是否有延迟,延迟大概是多长时间,这样达到数据不丢失。当然还有另外的方法来处理延迟,我们这里只讲水位线。】

当A到达的时候,Watermarks为max{8}-3.5=8-3.5 = 4.5 < 10,不会触发计算
当B到达的时候,Watermarks为max(12.5,8)-3.5=12.5-3.5 = 9 < 10,不会触发计算
当C到达的时候,Watermarks为max(12.5,8,9)-3.5=12.5-3.5 = 9 < 10,不会触发计算
当D到达的时候,Watermarks为max(13.5,12.5,8,9)-3.5=13.5-3.5 = 10 = 10,触发计算
触发计算的时候,会将AC(因为他们都小于10)都计算进去

通过上面这种方式,我们就将迟到的C计算进去了

这里的延迟3.5s是我们假设一个数据到达的时候,比他早3.5s的数据肯定也都到达了,这个是需要根据经验推算的,加入D到达以后有到达了一个E,event-time=6,但是由于0~10的时间窗口已经开始计算了,所以E就丢了。

从这里上面E的丢失说明,水位线也不是万能的,但是如果根据我们自己的生产经验+侧道输出等方案,可以做到数据不丢失。

上面我们明白了水位线的机制,后面我们将进一步加深从代码搞懂水位线

最新经典文章,欢迎关注公众号http://www.aboutyun.com/data/attachment/forum/201406/15/084659qcxzzg8n59b6zejp.jpg


美丽天空 发表于 2019-3-18 23:48:12

感谢分享
页: [1]
查看完整版本: Flink难点解析1:揭开Watermark的神秘面纱【机制篇】