Flink Program Guide (4) -- 时间戳和Watermark生成(DataStream API编程指导 -- For Java)
时间戳和Watermark生成
本文翻译自Generating Timestamp / Watermarks
------------------------------------------------------------------
本文是Flink在使用事件时间(Event Time)时相关内容,有关事件时间、处理时间和提取时间的介绍,请见event time introduction。
流程序需要设置时间特征为Event time,才能在程序中使用事件时间。
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
一、时间戳赋值
为了使事件时间可以正常使用,Flink需要知道时间的时间戳,即流中的每个element都需要被赋予它自己的时间戳。Flink通常会从element的一些域访问/提取时间戳(That happens usually by
accessing/extracting the timestamp from some field in the element.)。
时间戳的赋值通常与Watermark的生成紧密相关,其中Watermark生成负责通知系统事件时间的增长情况。
时间戳赋值和Watermark生成的方式有两种:
1. 直接在数据流源处进行
2. 通过一个Timestamp
assigner / watermark generator:在Flink中,Timestamp assigner同样会定义watermark的发送行为
注意:时间戳和Watermark都是使用从Java历元(epoch)
“1970-01-01 T00.00.00Z”开始的毫秒数定义的
1.1 带有时间戳和Watermark的Source方法
流的源可以在它们生产的element中直接赋值时间戳以及发送Watermark。在此情况下,我们不需要Timestamp
Assigner。
要在Source方法中向element直接赋值时间戳,Source方法必须在SourceContext上调用方法collectWithTimestamp(…)。要在Source中生成Watermark,Source必须调用emitWatermark(Watermark)方法。
在下例的(非检查点的)Source方法中,方法直接向element赋值时间戳,并且根据特殊事件生成Watermark:
@Override
public void run(SourceContext<MyType>
ctx) throws Exception {
while (/*
condition */) {
MyType
next = getNext();
ctx.collectWithTimestamp(next,
next.getEventTimestamp());
if
(next.hasWatermarkTime())
{
ctx.emitWatermark(new
Watermark(next.getWatermarkTime()));
}
}
}
注意:如果流程序在已经拥有时间戳的流上继续使用TimestampAssigner,流中element的原有时间戳将被TimestampAssigner重写。类似地,Watermark也会同样被重写。
1.2 Timestamp Assigner / Watermark Generators
Timestamp
Assigner接收一个流并且产生一个带有时间戳赋值element和Watermark的新的流。如果原有的流已经拥有了时间戳或Watermark,则Timestamp
Assigner将会重写它们。
通常在紧接着数据源之后会定义Timestamp
Assigner,但这并不是严格要求的。例如在通用的模式中,会在Timestamp
Assigner之前进行parse(MapFunction)和filter(FilterFunction)操作。不论在什么情况下,Timestamp
Assigner都需要在第一个使用事件时间的Operation(如第一个窗口Operation)之前定义。而在流Job中使用Kafka作为数据源是一个特殊情况,Flink允许在数据源(或数据消费者consumer)内部定义Timestamp
Assigner和Watermark
emitter,更多相关信息请见Kafka Connector
documentation。
注意:本节余下内容呈现了一个开发者创建自己的Timestamp
Assigner 和 watermark
emitter所需要实现的主要接口。有关Flink自带的预先实现的extractor,请见Pre-defined Timestamp
Extractors / Watermark Emitters
final
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
DataStream<MyEvent>
stream = env.readFile(
myFormat, myFilePath, FileProcessingMode.PROCESS_CONTINUOUSLY,
100,
FilePathFilter.createDefaultFilter(),
typeInfo);
DataStream<MyEvent>
withTimestampsAndWatermarks = stream
.filter(
event -> event.severity()
== WARNING )
.assignTimestampsAndWatermarks(new
MyTimestampsAndWatermarks());
withTimestampsAndWatermarks
.keyBy( (event)
-> event.getGroup()
)
.timeWindow(Time.seconds(10))
.reduce( (a,
b) -> a.add(b)
)
.addSink(...);
周期性Watermark
AssignerWithPeriodicWatermark赋值时间戳并周期性生成(生成方式有可能是依靠流的element,或者纯粹基于处理时间)。
生成Watermark的时间周期区间(每n毫秒)的大小可以通过ExecutionConfig.setAutoWatermarkInterval(…)设置。每一次生成时,都将会调用Assigner的getCurrentWatermark()方法,如果返回的Watermark是非null且大于前一个Watermark,则会发送一个新的Watermark。
下面是两个生成周期性Watermark和Timestamp
Assigner的例子
/**
* This generator generates watermarks assuming that elements
come out of order to a certain degree only.
* The latest elements for a certain timestamp t will arrive at
most n milliseconds after the earliest
* elements for timestamp t.
*/
public class BoundedOutOfOrdernessGenerator extends
AssignerWithPeriodicWatermarks<MyEvent> {
private
final long maxOutOfOrderness = 3500;
// 3.5 seconds
private
long currentMaxTimestamp;
@Override
public long extractTimestamp(MyEvent
element, long previousElementTimestamp)
{
long timestamp = element.getCreationTime();
currentMaxTimestamp = Math.max(timestamp,
currentMaxTimestamp);
return timestamp;
}
@Override
public Watermark getCurrentWatermark()
{
// return the watermark as current highest timestamp minus the
out-of-orderness bound
return new Watermark(currentMaxTimestamp
- maxOutOfOrderness);
}
}
/**
* This generator generates watermarks that are lagging behind
processing time by a certain amount.
* It assumes that elements arrive in Flink after at most a
certain time.
*/
public class TimeLagWatermarkGenerator extends
AssignerWithPeriodicWatermarks<MyEvent> {
private
final long maxTimeLag = 5000;
// 5 seconds
@Override
public long extractTimestamp(MyEvent
element, long
previousElementTimestamp) {
return element.getCreationTime();
}
@Override
public Watermark getCurrentWatermark()
{
//
return the watermark as current time minus the maximum time lag
return new Watermark(System.currentTimeMillis()
- maxTimeLag);
}
}
带标点(punctuated)Watermark
为了在某事件下就产生Watermark,我们需要使用AssignerWithPunctuatedWatermarks。在该类中,Flink会先调用extractTimestamp(…)方法来给element赋值一个时间戳,然后针对该element即刻调用checkAndGetNextWatermark(…)方法来返回一个非null的Watermark。
checkAndGetNextWatermark(…)方法将获得在extractTimestamp(…)方法中获得的时间戳,并决定是否生成Watermark。一旦checkAndGetNextWatermark(…)方法返回一个非null的Watermark,并且该Watermark大于最近的上一个Watermark,则发送该新的Watermark。
public
class PunctuatedAssigner extends
AssignerWithPunctuatedWatermarks<MyEvent> {
@Override
public long extractTimestamp(MyEvent
element, long
previousElementTimestamp) {
return element.getCreationTime();
}
@Override
public Watermark checkAndGetNextWatermark(MyEvent
lastElement, long
extractedTimestamp) {
return element.hasWatermarkMarker()
? new Watermark(extractedTimestamp)
: null;
}
}
注意:在每个事件上都生成一个Watermark是可能存在的,但是由于每个Watermark都会导致下游的计算开销,过多的Watermark会降低程序的性能
Flink Program Guide (4) -- 时间戳和Watermark生成(DataStream API编程指导 -- For Java)的更多相关文章
- Flink Program Guide (2) -- 综述 (DataStream API编程指导 -- For Java)
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...
- Flink Program Guide (10) -- Savepoints (DataStream API编程指导 -- For Java)
Savepoint 本文翻译自文档Streaming Guide / Savepoints ------------------------------------------------------ ...
- Flink Program Guide (6) -- 窗口 (DataStream API编程指导 -- For Java)
窗口(Window) 本文翻译自文档Windows ----------------------------------- Flink使用窗口的概念,根据element的时间戳或者其他指标,将可能无限 ...
- Flink Program Guide (5) -- 预定义的Timestamp Extractor / Watermark Emitter (DataStream API编程指导 -- For Java)
本文翻译自Pre-defined Timestamp Extractors / Watermark Emitter ------------------------------------------ ...
- Flink Program Guide (3) -- Event Time (DataStream API编程指导 -- For Java)
Event Time 本文翻译自DataStream API Docs v1.2的Event Time ------------------------------------------------ ...
- Flink Program Guide (8) -- Working with State :Fault Tolerance(DataStream API编程指导 -- For Java)
Working with State 本文翻译自Streaming Guide/ Fault Tolerance / Working with State ---------------------- ...
- 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 ...
- 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 ...
- Flink Program Guide (9) -- StateBackend : Fault Tolerance(Basic API Concepts -- For Java)
State Backends 本文翻译自文档Streaming Guide / Fault Tolerance / StateBackend ----------------------------- ...
随机推荐
- directive和controller如何通信
1.AngularJS是何方神圣 Angular JS (Angular.JS) 是一组用来开发Web页面的框架.模板以及数据绑定和丰富UI组件.它支持整个开发进程,提供web应用的架构,无需进行手工 ...
- shonc项目中的设计资讯模块 php 字符串操作与正则表达式 strip_tags preg_match
问题:当description 内容要求description的值选用资讯内容的前50个汉字.资讯内容可能有图片. 此时需要对输出的内容进行处理 php 正则表达式处理,编辑器输出的内容 只取图片: ...
- php的多线程使用
PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程.多线程在处理重复性的循环任务,能够大大缩短程序执行时间. 在liunx下的安装 准备工作: 1.下载Threa ...
- LaTeX中titlesec宏包的使用
在 xelatex 中使用 \usepackage 指令使用 titlesec 宏包时,可以指定一些格式选项,如下: \usepackage[center]{titlesec} 其中 center 可 ...
- 03-树2. Tree Traversals Again (25)
03-树2. Tree Traversals Again (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue ...
- App_Code
App_Code,文件夹是·NET平台下.在创建网站时,系统为类自动放的位置.它位于Web应用程序根目录下,其存储所有应当作为应用程序的一部分动态编译的类文件.这些类文件自 动链接到应用程序,而不需要 ...
- 进程外Session和进程内Session存储
- 四大图像库:OpenCV/FreeImage/CImg/CxImage
1.对OpenCV 的印象:功能十分的强大,而且支持目前先进的图像处理技术,体系十分完善,操作手册很详细,手册首先给大家补计算机视觉的知识,几乎涵盖了近10年内的主流算法: 然后将图像格式和矩阵运算, ...
- linux文件属性
在Linux中,文件的属性是一个很重要的概念,用户或者用户组对一个文件所拥有的权限,都可以 从文件的属性得知.我们可以通过ls -al命令,列出某个文件夹下面的所有文件(包括以.开头的隐藏 文件).下 ...
- HDOJ-1002 A + B Problem II (非负大整数相加)
http://acm.hdu.edu.cn/showproblem.php?pid=1002 输入的数都是正整数,比较好处理,注意进位. //非负大整数加法 # include <stdio.h ...