大家好,今天我们来聊一聊flink的Watermark机制。

这也是flink系列的的第一篇文章,如果对flink、大数据感兴趣的小伙伴,记得点个关注呀。

背景

​ flink作为先进的流水计算引擎,提供了三种时间概念,这对基于时间的流处理应用提供了多种可能。

  • Event time 指生产设备中每个独立的事件发生的时间,比如用户点击产生的时间。

  • Process time 指正在执行相关进程的机器的系统时间。

  • IngestionTime 指事件进入flink的时间。

WaterMark机制主要是用来解决EventTime乱序的情况。从事件的产生、到经过消息中间件、然后经过data source和Operator,在传输的过程中,由于网络传输等原因,会导致EventTime出现乱序,如果只是根据EventTime来决定window的运行,我们不能明确数据是否已经全部到位,所以我们需要有一个机制来保证特定的时间后,必须触发window去执行计算了,这个机制就是Watermark。

定义

WaterMark是一种特殊的时间戳,它会被插入到数据流中,用于表示EventTime小于Watermark的事件全部落入到了相应的窗口中。

如图所示,这是一个窗口大小为5的乱序流。w(5)表示EventTime小于5的数据已经落入相应的窗口。当Watermark大于等于窗口的最大时间戳(即窗口的endTime),就会触发相应窗口的计算。比如W(5)大于等于5,会触发窗口[0,5)的计算。

生成

WaterMark有两种生成方式,分别是Punctuated Watermark(标点水位线)和Periodic Watermark(周期性水位线)。

  • 标点水位线

    标点水位线(Punctuated Watermark)是通过数据流中某些特殊标记事件来触发新水位线的生成。这种方式下,窗口的触发与时间无关,而是决定于何时收到标记事件。在实际的生产中Punctuated方式在TPS很高的场景下会产生大量的Watermark在一定程度上对下游算子造成压力,所以只有在实时性要求非常高的场景才会选择Punctuated的方式进行Watermark的生成。

  • 周期性水位线

    周期性的(允许一定时间间隔或者达到一定的记录条数)产生一个Watermark。水位线提升的时间间隔是由用户设置的,在两次水位线提升时隔内会有一部分消息流入,用户可以根据这部分数据来计算出新的水位线。在实际的生产中Periodic的方式必须结合时间和积累条数两个维度继续周期性产生Watermark,否则在极端情况下会有很大的延时。

案例

在实际的项目中,主要是使用周期性的水位线,我们可以通过env.getConfig().setAutoWatermarkInterval()设置,默认是200ms。

public class test {
public static void main(String[] args) throws Exception { StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.getConfig().setAutoWatermarkInterval(100); DataStreamSource<String> inputStream = env.socketTextStream("localhost", 8888); SerializableTimestampAssigner<String> timestampAssigner =
new SerializableTimestampAssigner<String>(){
@Override
public long extractTimestamp(String element, long recordTimestamp) {
String[] fields = element.split(" ");
Long aLong = new Long(fields[0]);
return aLong * 1000L;
}
}; SingleOutputStreamOperator<Tuple2<String,Long>> result=inputStream.assignTimestampsAndWatermarks(
WatermarkStrategy
.<String>forBoundedOutOfOrderness(Duration.ofSeconds(5))
.withTimestampAssigner(timestampAssigner)
).map(new MapFunction<String, Tuple2<String,Long>>() {
@Override
public Tuple2<String, Long> map(String s) {
return Tuple2.of(s.split(" ")[1],1L);
}
}).keyBy(0)
.window(TumblingEventTimeWindows.of(Time.seconds(10)))
.reduce(new ReduceFunction<Tuple2<String, Long>>() {
@Override
public Tuple2<String, Long> reduce(Tuple2<String, Long> stringLongTuple2, Tuple2<String, Long> t1) throws Exception {
return new Tuple2<>(stringLongTuple2.f0,stringLongTuple2.f1+t1.f1);
}
});
result.print();
env.execute("warter mark test"); }
}

当通过nc -l 8888输入数据

1630312530 java
1630312533 java
1630312536 java
1630312540 java
1630312543 java
1630312538 java
1630312545 java
1630312539 java
1630312550 java
1630312549 java
1630312555 java

输出为:

1> (java,5)
1> (java,4)

当事件“1630312545 java”进入流处理后,生成的Watermark为“W(1630312540)”,大于等于窗口[1630312530,1630312540)的endTime,触发窗口的计算,此时延迟数据“1630312538 java”也会被计算在内,所以会输出“(java,5)”,而事件“1630312539 java”是在Watermark已经触发相应的窗口计算后,才进入流处理中,延迟太久,会被忽略掉。当事件“163031255 java”进入流处理后,生成的Wartermark为W(163031250),触发窗口[163031240,163031250)的计算。

最后

到此为止,我们已经把Watermark机制聊完了,如果喜欢,请点个关注吧。

更多有趣知识,请关注公众号【程序员学长】。我给你准备了上百本学习资料,包括python、java、数据结构和算法等。如果需要,请关注公众号【程序员学长】,回复【资料】,即可得。

你知道的越多,你的思维也就越开阔,我们下期再见。

flink的watermark机制你学会了吗?的更多相关文章

  1. [白话解析] Flink的Watermark机制

    [白话解析] Flink的Watermark机制 0x00 摘要 对于Flink来说,Watermark是个很难绕过去的概念.本文将从整体的思路上来说,运用感性直觉的思考来帮大家梳理Watermark ...

  2. Flink的时间类型和watermark机制

    一FlinkTime类型 有3类时间,分别是数据本身的产生时间.进入Flink系统的时间和被处理的时间,在Flink系统中的数据可以有三种时间属性: Event Time 是每条数据在其生产设备上发生 ...

  3. [源码解析] 从TimeoutException看Flink的心跳机制

    [源码解析] 从TimeoutException看Flink的心跳机制 目录 [源码解析] 从TimeoutException看Flink的心跳机制 0x00 摘要 0x01 缘由 0x02 背景概念 ...

  4. Flink(八)【Flink的窗口机制】

    目录 Flink的窗口机制 1.窗口概述 2.窗口分类 基于时间的窗口 滚动窗口(Tumbling Windows) 滑动窗口(Sliding Windows) 会话窗口(Session Window ...

  5. Flink Runtime核心机制剖析(转)

    本文主要介绍 Flink Runtime 的作业执行的核心机制.本文将首先介绍 Flink Runtime 的整体架构以及 Job 的基本执行流程,然后介绍在这个过程,Flink 是怎么进行资源管理. ...

  6. Apache Flink - 数据流容错机制

    Apache Flink提供了一种容错机制,可以持续恢复数据流应用程序的状态.该机制确保即使出现故障,程序的状态最终也会反映来自数据流的每条记录(只有一次). 从容错和消息处理的语义上(at leas ...

  7. Flink Window窗口机制

    总览 Window 是flink处理无限流的核心,Windows将流拆分为有限大小的"桶",我们可以在其上应用计算. Flink 认为 Batch 是 Streaming 的一个特 ...

  8. [Flink] Flink的waterMark的通俗理解

    导读 Flink 为实时计算提供了三种时间,即事件时间(event time).摄入时间(ingestion time)和处理时间(processing time). 遇到的问题: 假设在一个5秒的T ...

  9. Flink – process watermark

    WindowOperator.processElement 主要的工作,将当前的element的value加到对应的window中, windowState.setCurrentNamespace(w ...

随机推荐

  1. MySQL问题定位-性能优化之我见

    前言 首先任何一个数据库不是独立存在的,也不是凭空想象决定出来的. 数据库的架构离不开应用的场景.所以,为了解决某些深入的问题,首先你得掌握数据库的原理与架构.原理掌握得越深入,越能帮助你定位复杂与隐 ...

  2. ML - 常用数学符号

    关系运算符: ±:\pm ×:\times ÷:\div ∣:\mid ∤:\nmid ⋅:\cdot ∘:\circ ∗:\ast ⨀:\bigodot ⨂:\bigotimes ⨁:\bigopl ...

  3. CSP-S 2020 初赛

    游记 游记个鬼啊跨条街就到了=-= 不分Day反正就一天. 9:30开考,8:30起床. 下雨了,一出宿舍门整个学校全被白色的雾气笼罩.愚以为这是祥瑞之气,昨夜似有麒麟貔貅路过,祝我今日初赛RP++ ...

  4. jvm源码解读--14 defNewGeneration.cpp gc标记复制之后,进行空间清理

    进入Eden()->clean()函数 void EdenSpace::clear(bool mangle_space) { ContiguousSpace::clear(mangle_spac ...

  5. jquery 对HTML标签的克隆、删除

    <table width="100%" class="table_form"> <tr> <td>奖励深度(<a hr ...

  6. Redis.conf分析

    Redis.conf 单位 配置文件对大小写不敏感 # 1k => 1000 bytes # 1kb => 1024 bytes # 1m => 1000000 bytes # 1m ...

  7. 王者并发课-钻石2:分而治之-如何从原理深入理解ForkJoinPool的快与慢

    欢迎来到<王者并发课>,本文是该系列文章中的第25篇,砖石中的第2篇. 在上一篇文章中,我们学习了线程池ThreadPoolExecutor,它通过对任务队列和线程的有效管理实现了对并发任 ...

  8. .Net Core微服务——Consul(4):主从、集群

    延续上一篇的话题继续,顺便放上一篇的传送门:点这里. 集群的必要性 consul本身就是管理集群的,现在还需要给consul搞个集群,这是为啥?因为consul单点也容易挂啊!万一管理集群的consu ...

  9. Python学习的十个阶段,学完神功大成,对应一下看看你自己在哪个阶段

    大家好,我是白云. 今天给大家整理了Python学习的十个阶段内容,看看你现在正处于哪个阶段,想学习的朋友也可以根据这个阶段规划学习. 阶段一:Python基础[ 初入江湖] Linux基础 目标: ...

  10. MySQL的函数使用

    目录 COUNT()函数基本使用 SUM( )函数基本使用 AVG()函数基本使用 MAX()函数基本使用 MIN()函数基本使用 字符函数 concat()和concat_ws() LEFT()与R ...