时间戳和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)的更多相关文章

  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 (6) -- 窗口 (DataStream API编程指导 -- For Java)

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

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

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

  5. Flink Program Guide (3) -- Event Time (DataStream API编程指导 -- For Java)

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

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

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

  7. 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 ...

  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. 为什么所有浏览器的userAgent都带Mozilla

    参看下面链接:<为什么所有的浏览器的userAgent都带Mozilla>

  2. discuz二次开发笔记(三)------discuz的安装步骤

    下载好discuz的安装包后,解压在自己定义的文件夹里面,将upload里面的文件拷贝出来放到和upload同级的地方,然后删除upload文件夹. 打开浏览器,输入你文件夹的地址:如:http:// ...

  3. [ofbiz]entitymode中类型的对照关系

    在实体数据结构的时候,习惯于数据库的设计模式,int,varchar等各种类型,但是在entitymode中不是直接使用数据库的类型模式,而是自己定义了一套数据类型(type). 如何找到两者之间的对 ...

  4. 判断浏览器IE6

    <!--[if lte IE 6]><LINK rel="stylesheet" type="text/css" href="ima ...

  5. Servlet基础之一:Servlet基本接口与类

    1.概述 Servlet API中共有5个包,约113个接口和类: javax.servlet javax.servlet.http javax.servlet.jsp javax.servlet.a ...

  6. [汇编语言]-第二章DEBUG

    Debug查看CPU各种寄存器中得内容,内存的情况和在机器码级跟踪程序的运行. 1- 进入Debug xp 开始-运行 cmd 输入 debug 2- Debug功能 r 查看,改变CPU寄存器的内容 ...

  7. Android的线程和线程池

    ---恢复内容开始--- 一.Android线程的形态 (一)AsyncTask解析 AysncTask简介:①.实现上封装了Thread和Handler   ②.不适合进行特别耗时的后台任务 Ays ...

  8. struts2_20140720

    有这样的感觉:前面学的东西弄会了,过了一段时间又感觉陌生了,还要重新开始.这次想个好办法,把写的程序用博客记录下来,把自己的学历历程用博客的形式呈现出来,一来可以方便复习,而来可以以后开发程序可以快速 ...

  9. JavaEE Tutorials (27) - Java EE的并发工具

    27.1并发基础427 27.1.1线程和进程42827.2并发工具的主要组件42827.3并发和事务42927.4并发和安全43027.5jobs并发示例430 27.5.1运行jobs示例4302 ...

  10. Ubuntu 12.04安装NFS server

    首先安装nfs-kernel-server apt-get install nfs-kernel-server 然后创建一个目录: mkdir -p /opt/share 并赋予权限777: chmo ...