Flink - Generating Timestamps / Watermarks
To work with Event Time, streaming programs need to set the time characteristic accordingly.
首先配置成,Event Time
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
Assigning Timestamps
In order to work with Event Time, Flink needs to know the events’ timestamps, meaning each element in the stream needs to get its event timestamp assigned. That happens usually by accessing/extracting the timestamp from some field in the element.
Timestamp assignment goes hand-in-hand with generating watermarks, which tell the system about the progress in event time.
There are two ways to assign timestamps and generate Watermarks:
- Directly in the data stream source
- Via a TimestampAssigner / WatermarkGenerator
接着,我们需要定义如何去获取event time和如何产生Watermark?
一种方式,在source中写死,
@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()));
}
}
}
这种方式明显比较low,不太方便,并且这种方式是会被TimestampAssigner 覆盖掉的,
所以看看第二种方式,
Timestamp Assigners / Watermark Generators
Timestamp Assigners take a stream and produce a new stream with timestamped elements and watermarks. If the original stream had timestamps or watermarks already, the timestamp assigner overwrites those.
The timestamp assigners occur usually direct after the data source, but it is not strictly required to. A common pattern is for example to parse (MapFunction) and filter (FilterFunction) before the timestamp assigner. In any case, the timestamp assigner needs to occur before the first operation on event time (such as the first window operation).
一般在会在source后加些map,filter做些初始化或格式化
然后,在任意需要用到event time的操作之前,比如window,进行设置
给个例子,
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime); DataStream<MyEvent> stream = env.addSource(new FlinkKafkaConsumer09<MyEvent>(topic, schema, props)); 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(...);
那么Timestamp Assigners如何实现,比如例子中给出的MyTimestampsAndWatermarks
有3种,
With Ascending timestamps
The simplest case for generating watermarks is the case where timestamps within one source occur in ascending order. In that case, the current timestamp can always act as a watermark, because no lower timestamps will occur any more.
DataStream<MyEvent> stream = ... DataStream<MyEvent> withTimestampsAndWatermarks =
stream.assignTimestampsAndWatermarks(new AscendingTimestampExtractor<MyEvent>() { @Override
public long extractAscendingTimestamp(MyEvent element) {
return element.getCreationTime();
}
});
这种没人用吧,不如直接用processing time了
With Periodic Watermarks
The AssignerWithPeriodicWatermarks assigns timestamps and generate watermarks periodically (possibly depending the stream elements, or purely based on processing time).
The interval (every n milliseconds) in which the watermark will be generated is defined via ExecutionConfig.setAutoWatermarkInterval(...). Each time, the assigner’s getCurrentWatermark() method will be called, and a new Watermark will be emitted, if the returned Watermark is non-null and larger than the previous Watermark.
定期的发送,你可以通过ExecutionConfig.setAutoWatermarkInterval(...),来设置这个频率
/**
* 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);
}
}
上面给出两个case,区别是第一种,会以event time的Max,来设置watermark
第二种,是以当前的processing time来设置watermark
With Punctuated Watermarks
To generate Watermarks whenever a certain event indicates that a new watermark can be generated, use theAssignerWithPunctuatedWatermarks. For this class, Flink will first call the extractTimestamp(...) method to assign the element a timestamp, and then immediately call for that element the checkAndGetNextWatermark(...) method.
The checkAndGetNextWatermark(...) method gets the timestamp that was assigned in the extractTimestamp(...) method, and can decide whether it wants to generate a Watermark. Whenever the checkAndGetNextWatermark(...) method returns a non-null Watermark, and that Watermark is larger than the latest previous Watermark, that new Watermark will be emitted.
这种即,watermark不是由时间来触发的,而是以特定的event触发的,即本到某些特殊的event或message,才触发watermark
所以它的接口叫,checkAndGetNextWatermark
需要先check
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;
}
}
Flink - Generating Timestamps / Watermarks的更多相关文章
- flink Window的Timestamps/Watermarks和allowedLateness的区别
Watermartks是通过additional的时间戳来控制窗口激活的时间,allowedLateness来控制窗口的销毁时间. 注: 因为此特性包括官方文档在1.3-1.5版本均未做改变,所以 ...
- 【翻译】生成 Timestamps / Watermarks
本文翻译自flink官网:https://ci.apache.org/projects/flink/flink-docs-release-1.7/dev/event_timestamps_waterm ...
- Flink - watermark生成
参考,Flink - Generating Timestamps / Watermarks watermark,只有在有window的情况下才用到,所以在window operator前加上assig ...
- Flink Program Guide (3) -- Event Time (DataStream API编程指导 -- For Java)
Event Time 本文翻译自DataStream API Docs v1.2的Event Time ------------------------------------------------ ...
- flink学习之十一-window&EventTime实例
上面试了Processing Time,在这里准备看下Event Time,以及必须需要关注的,在ET场景下的Watermarks. EventTime & Watermark Event t ...
- Flink Program Guide (4) -- 时间戳和Watermark生成(DataStream API编程指导 -- For Java)
时间戳和Watermark生成 本文翻译自Generating Timestamp / Watermarks --------------------------------------------- ...
- Flink学习(二)Flink中的时间
摘自Apache Flink官网 最早的streaming 架构是storm的lambda架构 分为三个layer batch layer serving layer speed layer 一.在s ...
- Flink中的多source+event watermark测试
这次需要做一个监控项目,全网日志的指标计算,上线的话,计算量应该是百亿/天 单个source对应的sql如下 最原始的sql select pro,throwable,level,ip,`count` ...
- [白话解析] Flink的Watermark机制
[白话解析] Flink的Watermark机制 0x00 摘要 对于Flink来说,Watermark是个很难绕过去的概念.本文将从整体的思路上来说,运用感性直觉的思考来帮大家梳理Watermark ...
随机推荐
- c++find函数用法
头文件 #include <algorithm> 函数实现 template<class InputIterator, class T> InputIterator find ...
- C++的那些事:函数全解析
一.函数的结构 函数在C++中可能出现在三种地方,一是函数的定义,它包括了如上图的结构:二是函数的声明,它与函数的定义相比,没有了函数体部分:三则是函数的调用.当然,不同的函数定义可以还会稍有不同,比 ...
- 使用supervisor提高nodejs调试效率 (已验证)
开发 Node.js 实现的 HTTP 应用时会发现,无论你修改了代码的哪一部份,都必须终止Node.js 再重新运行才会奏效. 这是因为 Node.js 只在第一次引用到某部份时才会去解析脚本文件, ...
- 关于sqoop与datax。 和sqoop to oracle插件OraOop
之前我还在想了解下datax,是否有可能替换sqoop,但了解后发现,datax和sqoop的业务场景是不同的.前者适合异构数据库的同步,后者适合hdfs与rdbms互相之间的同步.针对sq ...
- css的引入方法
1.外部途径: 建立xx.css文件与html文件放在同一目录下 加入 <link rel="stylesheet" type="text/css" hr ...
- BZOJ3821 : 玄学
对操作建立线段树,每个节点维护一个有序的操作表,表示用$[l,r]$的操作在每段区间上的作用效果. 对于一个线段树节点,合并左右儿子信息只在该区间刚刚被填满时进行,利用归并排序,时间复杂度为$O(n\ ...
- Genymotion填坑之路
Genymotion是一款android的模拟器,之前用的一台电脑直接装上就可以用,后来换了一台机器,一直报获取不到IP,后来网上各种找方法,偶然发现网上说的是硬件问题: 在BIOS中将CPU的vir ...
- 移动端JD首页H5页面
1:理解View :<meta name="viewport" content="width=device-width,initial-scale=1.0" ...
- Java虚拟机(JVM)中的内存设置详解
在一些规模稍大的应用中,Java虚拟机(JVM)的内存设置尤为重要,想在项目中取得好的效率,GC(垃圾回收)的设置是第一步. PermGen space:全称是Permanent Generation ...
- java--测体重练习
public class tz{ public static void main(String[] args){ int sg=165,tz=52;bz = sg-115 if (tz-bz>3 ...