Flink水位线理解(带图且详细)

问题导读

1.什么是水位线?
2.水位线的作用是什么?
3.水位线的本质是什么?
4.水位线是为了解决什么问题?

刚接触Flink,可能你听说过“水印”或则“水位线”,但是技术领域为何会出现非技术词汇,到底什么是水位线,这两个陌生的词汇,给Flink蒙上了一层神秘的面纱。

这里我们就为大家揭开Watermark的神秘面纱。

回到Flink场景中来,Flink被称为终极流式框架,它是真正的流式处理,认为批处理是流处理的特殊情况,整因为这样,Flink统一了流处理和批处理。

我们这里的水位线,说的就是流处理事件中一个概念或则说流处理过程中遇到问题的解决方案。
在说水位线之前,为了照顾新手,我们首先需要明白什么是流处理?

所谓的流处理,最本质的是在处理数据的时候,是接受一条处理一条数据。而批处理,则是累积数据到一定程度在处理。这是他们本质的区别。

流数据异常该怎么办:

上面我们明白了什么是流处理,先不要着急去想什么Watermark,假如我们自己写一个流式框架。我们该如何处理消息。如下,我们看到消息按照顺序一个个发送,接受后按照顺序处理,这是没有什么问题的。

然而在来看下面情况:
消息不在是按照顺序发送,产生了乱序,这时候该怎么处理?

如果你看到这里,相信很多人可以猜出来了,水位线-Watermark是其中的解决方案之一。

看到这里其实可能还是懵逼状态,水位线怎么能解决这个乱序。

为了更好地明白下面讲的内容,补充下Flink的一些基本知识。
1.Flink 窗口(Window)
对于Flink如果来一条消息计算一条,这样是可以的,但是这样计算是非常频繁而且消耗资源,如果想做一些统计这是不可能的。所以对于Spark和Flink都产生了窗口计算。对于窗口感兴趣可参考Flink实时性、容错机制、窗口等介绍

2.事件时间
我们知道一个事件发生了,肯定是有时间的,这个时间,在Flink中被称之为事件时间,也就是Event Time。当然还有其它时间,如感兴趣可参考Flink系统学习11:【Flink1.7】事件时间、处理时间、提取时间有什么区别
上面两个概念明白了,我们就要讲:

watermark有什么用?
watermark是用于处理乱序事件的,而正确的处理乱序事件,通常用watermark机制结合window来实现。

我们知道,流处理从事件产生,到流经source,再到operator,中间是有一个过程和时间的。虽然大部分情况下,流到operator的数据都是按照事件产生的时间顺序来的,但是也不排除由于网络、背压等原因,导致乱序的产生(out-of-order或者说late element)。

但是对于late element,我们又不能无限期的等下去,必须要有个机制来保证一个特定的时间后,必须触发window去进行计算了。这个特别的机制,就是watermark。

如何使用Watermarks处理乱序的数据流?
什么是乱序呢?如上面图示,可以理解为数据到达的顺序和他的event-time(事件发生时间)排序不一致。导致这的原因有很多,比如延迟,消息积压,重试等等

因为Watermarks是用来触发window窗口计算的,我们可以根据事件的event-time,计算出Watermarks,并且设置一些延迟,给迟到的数据一些机会,也就是说正常来讲,对于迟到的数据,我只等你一段时间,再不来就没有机会了。

这里我们需要稍微解释下:窗口的触发机制,比如滚动窗口,或则滑动窗口等,他们都是有自己的触发机制的,比如每隔5秒,窗口就会计算一次,也就是说,每隔5秒窗口就会触发一次。如对窗口计算不了解或则感兴趣,可参考Flink实时性、容错机制、窗口等介绍。这里不再详述。

我们明白了窗口的触发机制,这里我们添加了水位线,到底是个怎么个情况?我们来看下面
假如我们设置10s的时间窗口(window),那么010s,1020s都是一个窗口,以0~10s为例,0位start-time,10为end-time。假如有4个数据的event-time分别是8(A),12.5(B),9©,13.5(D),我们设置Watermarks为当前所有到达数据event-time的最大值减去延迟值3.5秒,也就是说对于迟到的数据,我们只等你3.5秒。【这里你可能有个问题,如果超过3.5秒该怎么办,这时候就需要我们对生产环境有一个整体的认识和把握,数据是否有延迟,延迟大概是多长时间,这样达到数据不丢失。当然还有另外的方法来处理延迟,我们这里只讲水位线。】

当A到达的时候,Watermarks为max{8}-3.5=8-3.5 = 4.5 < 10,不会触发计算
当B到达的时候,Watermarks为max(12.5,8)-3.5=12.5-3.5 = 9 < 10,不会触发计算
当C到达的时候,Watermarks为max(12.5,8,9)-3.5=12.5-3.5 = 9 < 10,不会触发计算
当D到达的时候,Watermarks为max(13.5,12.5,8,9)-3.5=13.5-3.5 = 10 = 10,触发计算
触发计算的时候,会将AC(因为他们都小于10)都计算进去

通过上面这种方式,我们就将迟到的C计算进去了

这里的延迟3.5s是我们假设一个数据到达的时候,比他早3.5s的数据肯定也都到达了,这个是需要根据经验推算的,加入D到达以后有到达了一个E,event-time=6,但是由于0~10的时间窗口已经开始计算了,所以E就丢了。

从这里上面E的丢失说明,水位线也不是万能的,但是如果根据我们自己的生产经验+侧道输出等方案,可以做到数据不丢失。

转载自:https://www.aboutyun.com/thread-26843-1-1.html
感谢作者,我终于明白了!

<think>好的,用户想理解Flink中的水位线和窗口机制,需要详细解释和示例。首先我得回忆下Flink的基本概念,水位线(Watermark)是用来处理事件时间乱序的机制,而窗口则是将无限数据流切分成有限块进行处理的方式。用户可能已经有一些流处理的基础,但需要更深入的机制解析。 根据用户提供的引用内容,我需要整合这些信息。比如引用[4]提到水位线是插入到数据流中的特殊标记,时间戳单调递增,并可以设置延迟处理乱序数据。而窗口部分,引用[2]和[3]分别解释了滑动窗口和滚动窗口的分配方式。用户给的示例中提到了水位线如何触发窗口关闭,比如事件15导致水位线超过窗口结束时间,从而关闭窗口,这需要详细说明。 用户可能想知道水位线和窗口是如何协同工作的,特别是水位线如何影响窗口的触发和数据的延迟处理。比如引用[1]中的例子,水位线延迟允许处理晚到的数据,避免数据被丢弃。这部分需要结合水位线的生成和窗口的lateness属性来解释。 另外,用户可能需要实际代码示例来理解如何应用这些概念。引用[3]中有代码片段关于创建滚动窗口,可以引用并扩展,展示如何设置水位线延迟和窗口函数。同时,要确保示例符合用户提到的使用$$...$$格式,比如数学公式的正确排版。 还需要考虑用户可能的疑问点,比如水位线的时间戳计算、窗口的类型(滚动、滑动、会话)、窗口分配器的作用等。需要分步骤解释,从水位线生成到窗口触发,再到数据处理,确保逻辑清晰。 最后,生成相关问题时要围绕核心概念,比如水位线延迟的影响、不同窗口类型的适用场景、如何优化水位线设置等,帮助用户进一步深入学习。同时,引用标记要正确添加,比如在解释水位线延迟时引用[1]和[4]。 总结下,回答的结构应该是先解释水位线和窗口的基本概念,再详细说明它们的工作原理和协同过程,接着给出代码示例,最后总结关键点。过程中需要引用提供的材料,确保信息准确,并用中文简洁明了地表达。</think>### Flink水位线与窗口机制解析 #### 一、水位线(Watermark)核心特性 1. **时间戳标记**:水位线是嵌入数据流的特殊标记,携时间戳$T$,表示事件时间进展到$T$[^4] 2. **乱序处理**:通过延迟设置(如允许5秒延迟)处理迟到数据,水位线时间戳计算方式为: $$ Watermark = max(当前事件时间) - 延迟时间 $$ 3. **单调递增**:确保事件时间始终向前推进,避免时间回退导致逻辑错误[^4] #### 二、窗口机制类型 | 窗口类型 | 特点描述 | 数学表达式示例 | |------------------|--------------------------------------------------------------------------|-----------------------------| | 滚动窗口 | 无重叠区间,固定时间划分 | $[t_0, t_0+5s)$ | | 滑动窗口 | 允许重叠区间,定义窗口大小与滑动步长 | 窗口大小=2s,滑动步长=1s[^2] | | 会话窗口 | 根据数据活跃度动态划分 | 会话间隔>阈值时分割 | #### 三、协同工作原理 1. **窗口生命周期** - 创建:数据首次进入窗口范围时生成 - 关闭:当水位线$T_w \geq 窗口结束时间T_{end}$时触发[^1] 2. **迟到数据处理** 通过`allowedLateness`设置额外容忍延迟: ```java .window(TumblingEventTimeWindows.of(Time.seconds(5))) .allowedLateness(Time.seconds(2)) ``` #### 四、完整代码示例(事件时间处理) ```java DataStream<Tuple2<String, Long>> input = ...; DataStream<Tuple2<String, Long>> result = input .assignTimestampsAndWatermarks( WatermarkStrategy.<Tuple2<String, Long>>forBoundedOutOfOrderness(Duration.ofSeconds(5)) .withTimestampAssigner((event, timestamp) -> event.f1)) .keyBy(event -> event.f0) .window(TumblingEventTimeWindows.of(Time.seconds(10))) .allowedLateness(Time.seconds(3)) .reduce((a, b) -> new Tuple2<>(a.f0, a.f1 + b.f1)); ``` #### 五、关键过程解析 1. **水位线触发条件** 当事件21(时间戳22:07:16)到达时: $$ Watermark = 22:07:16 - 5s = 22:07:11 > 窗口结束时间22:07:10 $$ 触发窗口关闭并输出计算结果[^1] 2. **延迟窗口关闭优势** 事件13(时间戳22:07:08)虽晚于窗口理论关闭时间,但因水位线延迟设置仍被正确处理[^1] #### 六、配置优化建议 1. 根据网络延迟情况设置合理的水位线延迟 2. 使用`sideOutputLateData`捕获超时数据进行分析 3. 会话窗口适用于用户行为分析等非固定时间间隔场景
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值