Event Time

本文翻译自DataStream API Docs v1.2的Event Time

-------------------------------------------------------

一、事件时间 / 处理时间 / 提取时间

Flink支持流程序不同的time概念。

·        Processing time:处理时间指执行对应Operation的设备的系统时间。

当一个流程序以处理时间运行,所有基于时间的operation(如time窗口)将使用运行对应Operation的设备的系统时钟。例如,一个每小时触发的时间窗口将包含在系统时钟走过一小时的事件内到达特定operator的所有数据。

处理时间是时间的最简单概念,并且不需要stream和设备之间的协调。它提供了最佳的性能和最低的执行时间。但是,在分布式异步环境中,由于数据到达系统的速度(如从信息队列中到达的数据)以及在系统内部Operator之间流动速度都十分容易受到影响,故处理时间无法提供确定性(determinism)。

·        Event time:事件时间是每个单独事件在它的生产设备上发生的时间。该时间通常在数据进入Flink之前就会被集成进数据,且event timestamp是可以从数据中抽取出来的。一个每小时事件的时间窗口将包含所有带有一个小时内的时间戳的数据,而不管这些数据是什么时候到达,也不管它们是以什么顺序到达的。

即使在乱序事件、迟到事件以及备份或持久日志的数据重放等多种的情形下,事件时间也可以给我们提供正确的结果。在事件时间中,时间的增长依靠数据,而不依赖于任何wall clock。事件时间程序必须定义如何生成Event Time Watermarks,这是在事件时间中标识时间增长的机制,有关该机制将在下面描述。

在事件时间处理中,由于它本质上会等待迟到事件和乱序事件,总会导致一些延迟,因此,事件时间程序通常会与processing time operation结合

·        Ingestion Time:提取时间是事件进入Flink的时间,在Source Operator中,每个数据以source的当前时间作为时间戳,且基于时间的operator(如时间窗口)便使用该时间戳。

提取时间概念上处于Event Time和Processing Time之间。

a.     与处理时间相比,提取时间的开销稍微昂贵一些,但会给出更多可预见的结果:因为提取时间使用稳定的时间戳(在source上仅仅赋值一次),数据流过的不同的窗口Operator使用同一个时间戳。而在处理时间下,每个window operator可能将数据赋值给不同的窗口(根据本地系统时钟和任何传输延迟)。

b.    与事件时间相比,提取时间不能处理任何乱序事件或迟到数据,但是程序不需要定义如何生成Watermarks。在Flink内部,对待提取时间与事件时间相似,都有自动时间戳赋值以及自动水印生成功能。

1.1 设置时间特征

Flink DataStream程序的第一个部分通常是设置基础时间特征,它定义了数据流源是如何运行的(例如是否使用时间戳),以及诸如KeyedStream.timeWindow(Time.seconds(30))的窗口Operation使用的是哪种概念的时间。

接下来的例子是一个在每小时的窗口中聚合事件的Flink程序,窗口的运行方式与不同时间特征相匹配。

final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);

// alternatively:
//
env.setStreamTimeCharacteristic(TimeCharacteristic.IngestionTime);

//
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

DataStream<MyEvent>
stream = env.addSource(new
FlinkKafkaConsumer09<MyEvent>(topic, schema,
props));

stream.keyBy(
(
event) -> event.getUser()
)

.timeWindow(Time.hours(1))
.reduce(
(
a, b) -> a.add(b)
)

.addSink(...);

注意:若要以Event
Time运行示例,程序需要使用一个Event time source,或者注入一个Timestamp
Assigner & Watermark Generator
。这些方法描述了如何访问事件时间戳,以及该事件流会展示出怎样的时间上的乱序性。

下面的部分描述了TimestampsWatermarks里的普遍机制。有关如何在Flink的DataStream
API中使用Timestamp
assignment和watermark
generation,请查看Generating Timestamps
/ Watermarks

二、事件时间(Event
Time)和Watermarks

注意:Flink从Dataflow模型中实现了技术,为了更好介绍Event Time,请查看以下文章

·       
Tyler Akidau的Streaming 101

·       
Dataflow Model论文

一个支持事件时间的流处理器需要衡量事件时间增长的方式。例如,一个构建了每小时窗口的窗口Operator需要在其事件时间到达下一个小时的时刻接到通知,从而使其可以关闭下一个窗口。

事件时间可以独立于处理时间(Processing
Time)
(由wall clock衡量)增长。例如,在一个程序中,一个Operator的当前事件时间可以稍稍慢于处理时间(这是由接收最新element的延迟引起的)并且以相同速度增长。在另一个流程序中,由于通过使用在Kafka
topic(或另一个消息队列)中已经缓存的数据而实现的快进式读取,从而使得事件时间可以在几秒内增长几周。

Flink中衡量事件时间的机制是Watermarks。Watermark带有一个时间戳t,并作为流的一部分共同流动。一个Watermark(t)声明了事件时间已经走到了该流中的时间t,意味着所有时间戳t`<t的事件已经发生了。

下图是一个带有(逻辑)时间戳的事件流,在事件流中还有Watermark在其中流动。在该事件流中,事件按照其时间戳有序排列,这意味着watermark仅仅是数据流中简单的带有有序时间戳的周期性标记。

Watermark对于乱序流来说极其重要,正如下图所示的就是一个乱序流,其中的时间不以它们的时间戳顺序发生。Watermark在流中建立了一个点,该点表明时间戳早于该Watermark的时间戳的所有事件都已经发送了。一旦一个Operator接收到一个Watermark,该Operator便可以将其内部事件时钟(event
time clock)
的值推进到Watermark的值处。

2.1 并行流中的Watermark

Watermark是在source方法处生成的,也可以直接在source方法之后生成。每个source方法的并行子任务通常独立生成watermark。这些watermark定义了在某个特定的并行source中的事件时间。

随着Watermark在流程序中的流动,它们在到达Operator时推动了Operator中的事件时间前进。一个Operator一旦推进了它的事件时间,它就会在下游为它后继的Operator生成一个新的Watermark。

那些接收多个输入流的Operator(如keyBy(…)之后,或partition(…)方法后,或一个union方法)会在它的每个输入流上分别跟踪其各自事件时间,Operator当前的事件时间是它的所有输入的事件时间之间的最小值。随着输入流更新它们的事件时间,Operator的事件时间也随之更新。

下图是一个事件和Watermark流过并行系统、且Operator跟踪其事件时间的例子。

2.1迟到Element

某些element违反Watermark条件的情况是有可能出现的,这意味着即使在Watermark(t)发生后,还有带有时间戳t`<t的事件发生。事实上,在许多实际部署中,某些element可能会随机性地发生延迟,使我们不可能定义一个“某时间戳的所有事件都已发生”的时间点。此外,即便该延迟是有界的,由于延迟太多的watermark会对事件时间窗口造成太多延迟,这种情况通常也是不理想的。

由于上述几点,一些流程序会显式等待某数量的迟到element。而迟到element就是那些在已经过了迟到element的时间戳的系统事件时间时钟(该时钟以Watermark为信号)之后才到达的element

Flink Program Guide (3) -- Event Time (DataStream API编程指导 -- For Java)的更多相关文章

  1. Flink Program Guide (2) -- 综述 (DataStream API编程指导 -- For Java)

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  2. Flink Program Guide (10) -- Savepoints (DataStream API编程指导 -- For Java)

    Savepoint 本文翻译自文档Streaming Guide / Savepoints ------------------------------------------------------ ...

  3. Flink Program Guide (8) -- Working with State :Fault Tolerance(DataStream API编程指导 -- For Java)

    Working with State 本文翻译自Streaming Guide/ Fault Tolerance / Working with State ---------------------- ...

  4. Flink Program Guide (6) -- 窗口 (DataStream API编程指导 -- For Java)

    窗口(Window) 本文翻译自文档Windows ----------------------------------- Flink使用窗口的概念,根据element的时间戳或者其他指标,将可能无限 ...

  5. Flink Program Guide (4) -- 时间戳和Watermark生成(DataStream API编程指导 -- For Java)

    时间戳和Watermark生成 本文翻译自Generating Timestamp / Watermarks --------------------------------------------- ...

  6. Flink Program Guide (7) -- 容错 Fault Tolerance(DataStream API编程指导 -- For Java)

    false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-n ...

  7. Flink Program Guide (5) -- 预定义的Timestamp Extractor / Watermark Emitter (DataStream API编程指导 -- For Java)

    本文翻译自Pre-defined Timestamp Extractors / Watermark Emitter ------------------------------------------ ...

  8. Flink Program Guide (1) -- 基本API概念(Basic API Concepts -- For Java)

    false false false false EN-US ZH-CN X-NONE /* Style Definitions */ table.MsoNormalTable {mso-style-n ...

  9. Flink Program Guide (9) -- StateBackend : Fault Tolerance(Basic API Concepts -- For Java)

    State Backends 本文翻译自文档Streaming Guide / Fault Tolerance / StateBackend ----------------------------- ...

随机推荐

  1. [STOI2014]舞伴(dp)

    STOI是汕头OI...无聊翻到了去年的比赛题目,就写然后自己测了一下. 其实我很想吐槽为什么题目名是perm,perm好像和舞伴完全无关.. dp(x,s)=∑dp(x-1,s-{i}))(0< ...

  2. C# 调用c++报错可能性分析

    1.在调用之前,可以用工具(Dependency)检测下c++库所依赖的文件,看是否有错误.如果有错误,请先下补充所需运行环境. 2.如果c++ 函数 形参需要C#传入结构体,可如下: [Struct ...

  3. 重写QSqlTableModel的flags函数实现tableview中某些列不可编辑,某些可以编辑

    Qt中使用QsqlTableModel和QTableView来显示数据库的查询结果是非常方便的,但是为了使QTableView中某些了列不可用,就需要重写 Qt::ItemFlags flags(co ...

  4. 原生化:AnDevCon 2014 McVeigh 的主题演讲

    作者:Jeff McVeigh(Intel) 基于(至少部分)NDK的原生安卓应用程序占现在前1000 强的 60% 以上.该增长的原因很简单:开发商需要为用户提供超卓的体验(包括灵敏的反应.与丰富的 ...

  5. python编码格式

    python编码总结: 1).首先python有两种格式的字符串,str和unicode,其中unicode相当于字节码那样,可以跨平台使用. str转化为unicode可以通过unicode(),u ...

  6. 【转】aiohttp 源码解析之 request 的处理过程

    [转自 太阳尚远的博客:http://blog.yeqianfeng.me/2016/04/01/python-yield-expression/] 使用过 python 的 aiohttp 第三方库 ...

  7. Enormous Input Test Solved Problem code: INTEST

    import sys import psyco #一键优化库 psyco.full() def main(): n, k = map(int, sys.stdin.readline().strip() ...

  8. linux上应用随机启动

    这是个go项目,其他的可以参考. 首先要有个脚本比如demo #!/bin/bash # # etcd This shell script takes care of starting and sto ...

  9. C#调用C++DLL传递结构体数组的终极解决方案

    在项目开发时,要调用C++封装的DLL,普通的类型C#上一般都对应,只要用DllImport传入从DLL中引入函数就可以了.但是当传递的是结构体.结构体数组或者结构体指针的时候,就会发现C#上没有类型 ...

  10. 线性表之顺序表(C语言实现)

    线性表是从数据元素的逻辑结构上定义的. 这种数据元素的逻辑结构的特征如下: 1.除开第一个和最后一个元素之外.所有元素都有一个前驱元素和后继元素. 2.第一个元素无前驱元素,但有后继元素. 3.最后一 ...