Flink/Blink 原理漫谈(一)时间,watermark详解

系列文章目录

Flink/Blink 原理漫谈(零)运行时的组件

Flink/Blink 原理漫谈(一)时间,watermark详解

Flink/Blink 原理漫谈(二)流表对偶性和distinct详解

Flink/Blink 原理漫谈(三)state 有状态计算机制 详解

Flink/Blink 原理漫谈(四)window机制详解

Flink/Blink 原理漫谈(五)流式计算的持续查询实现 详解

Flink/Blink 原理漫谈(六)容错机制(fault tolerance)详解


文章目录

  • 系列文章目录
  • 一、 时间
  • 二、 watermark
    • 概念
    • 一个例子
    • 多流watermarks处理
  • 总结


一、 时间

一共有三种时间:event time,ingestion time,processing time

Event time:事件发生的时间
Ingestion time:数据进入flink的时间
Processing time:执行操作算子的本地系统时间
Flink/Blink 原理漫谈(一)时间,watermark详解_第1张图片
Watermark就是基于Event Time产生的,Blink系统正是利用Event Time和Watermark机制处理数据乱序问题的。Processing Time并不能提供确定性,因为它容易受到Event到达系统的速度(例如来自消息队列)以及记录在Blink系统内部的处理先后顺序的影响。Ingestion Time在概念上位于Event Time和Processing Time之间。

目前Blink SQL 层面向用户开发的时间类型是 Event Time和Processing Time.

二、 watermark

概念

通常来说,数据都是按照event time进入operator中的,但是由于分布式,网络延迟等等原因,先发生的事情反而会在后面传入。
Flink/Blink 原理漫谈(一)时间,watermark详解_第2张图片
这就出问题了啊,如果我们只是根据event time来决定是否关闭当前窗口,就可能永远也无法知道什么时候应该关闭当前窗口,因为我们总是无法明确什么时候,当前窗口的所有数据都到位了。这时候就要引入watermarks的概念。

很多网上的文章描述的watermark太冗长复杂了,我将先说明watermark的用途,再使用一个例子来讲解。

Watermarks一般用来处理乱序数据,数据流中的watermarks一般用来表示timestamp小于watermarks的数据都已经到达了。

一个例子

我们将watermark设置为延迟2秒,然后窗口是3秒中的所有数据占据一个窗口这时候我们有这两个数据桶。第一个数据桶放置[0,3)的数据,第二个放[3,6)的
Flink/Blink 原理漫谈(一)时间,watermark详解_第3张图片
这时候来了第一条数据,数据的时间戳是1,通过计算,watermarks = 1-2(延迟)=-1

Flink/Blink 原理漫谈(一)时间,watermark详解_第4张图片
数据来了,并且3s的窗口属于打开状态,我们可以把时间戳为1的这条数据放入数据桶中。
Flink/Blink 原理漫谈(一)时间,watermark详解_第5张图片
还是刚才的步骤,时间戳为2的数据来了,计算watermark为0,将数据放入数据桶中。
Flink/Blink 原理漫谈(一)时间,watermark详解_第6张图片
这时候出现了一个乱序数据,时间戳为4,这显然超出了第一个数据桶的范围,所以我们放入第二个数据桶中,但是我们计算发现watermarks为4-2=2,所以0-3秒的这个窗口并没有关闭,也就是说此时,我们如果收到了0-3秒的数据,仍然可以正常流程放入数据桶中的。
Flink/Blink 原理漫谈(一)时间,watermark详解_第7张图片
此时,3来了,和之前1,2的操作是一样的,但是注意,这时候的watermarks仍然是2,因为3-2=1,watermarks表示的是它之前的数据都到达了,所以不会往小了更新。
Flink/Blink 原理漫谈(一)时间,watermark详解_第8张图片
最后,5来了,watermarks=3,触发输出结果和计算,关闭3s前的所有窗口。
Flink/Blink 原理漫谈(一)时间,watermark详解_第9张图片
代码实现上面的内容如下:

CREATE TABLE source(
  ...,
  event_time TimeStamp,
  WATERMARK wk1 FOR event_time as withOffset(event_time, 2000) 
) with (
  ...
);

在这里我们需要思考一个问题,如果watermarks触发窗口关闭之后仍然有之前的信息来呢?
在sql api这一层上,我查了文档好像没办法了,但是如果是比较底层的api,这种情况是可以处理的,flink有三层保险机制:watermarks,allowedLateness,sideOutPutLateness。简单来说,allowedlateness就是允许再等待一会,sideOutPutLateness就是将后来的数据作为一条新的stream,之后再与本身的数据作union,但是在阿里常用的这里好像没法操作(也可能是我菜),所以这里不展开说了。

多流watermarks处理

在实际的Streaming计算中往往一个job中会处理多个Source的数据,对Source的数据进行GroupBy分组,那么来自不同Source的相同key值会都同一个处理节点,并携带各自的Watermark,Blink内部要保证Watermark要保持单调递增,多个Source的Watermark汇聚到一起时候可能不是单调自增的,这样的情况Blink内部是如何处理的呢?

看下面这种情况:有四个source向一个节点发送watermarks,此时的已经到达的watermarks分别是2,4,3,6,我们取最小的一个2作为这个节点的watermarks,并将event-time clock 2向下游传递。
Flink/Blink 原理漫谈(一)时间,watermark详解_第10张图片
当4传入后,最小的watermarks改变为3,event-time更新为3,将3广播给下游。
Flink/Blink 原理漫谈(一)时间,watermark详解_第11张图片

总结

Watermark 就是触发前一窗口的“关窗时间”,一旦触发关门那么以当前时刻
为准在窗口范围内的所有所有数据都会收入窗中。
只要没有达到水位那么不管现实中的时间推进了多久都不会触发关窗。

你可能感兴趣的:(Flink/Blink,原理漫谈,blink,flink,大数据,实时大数据,sql)