「如何实现流动式软件发布」线上课堂开课啦,快来报名参与课堂抽奖吧~ 了解详情
写点什么

Apache Flink 零基础入门(五):流处理核心组件 Time&Window 深度解析

2019 年 7 月 19 日

Apache Flink零基础入门(五):流处理核心组件Time&Window深度解析

本文是 Apache Flink 零基础入门系列文章的第五篇,重点为大家梳理一下 Flink 处理有限流的核心组件 Window,主要内容包括:为什么要有 Window; Window 中的三个核心组件 WindowAssigner、Trigger 和 Evictor;Window 中怎么处理乱序数据,乱序数据是否允许延迟,以及怎么处理迟到的数据;整个 Window 的数据流程,以及 Window 中怎么保证 Exactly Once 语义。


1. Window & Time 介绍

Apache Flink(以下简称 Flink) 是一个天然支持无限流数据处理的分布式计算框架,在 Flink 中 Window 可以将无限流切分成有限流,是处理有限流的核心组件,现在 Flink 中 Window 可以是时间驱动的(Time Window),也可以是数据驱动的(Count Window)。


下面的代码是在 Flink 中使用 Window 的两个示例




2. Window API 使用

从第一部分我们已经知道 Window 的一些基本概念,以及相关 API,下面我们以一个实际例子来看看怎么使用 Window 相关的 API。


代码来自 flink-examples:



上面的例子中我们首先会对每条数据进行时间抽取,然后进行 keyby,接着依次调用 window(),evictor(), trigger() 以及 maxBy()。下面我们重点来看 window(), evictor() 和 trigger() 这几个方法。


2.1 WindowAssigner, Evictor 以及 Trigger

Window 方法接收的输入是一个 WindowAssigner, WindowAssigner 负责将每条输入的数据分发到正确的 Window 中(一条数据可能同时分发到多个 Window 中),Flink 提供了几种通用的 WindowAssigner:tumbling window(窗口间的元素无重复),sliding window(窗口间的元素可能重复),session window 以及 global window。如果需要自己定制数据分发策略,则可以实现一个 class,继承自 WindowAssigner。



Tumbling Window



Sliding Window



Session Window



Global Window


Evictor 主要用于做一些数据的自定义操作,可以在执行用户代码之前,也可以在执行用户代码之后,更详细的描述可以参考 org.apache.flink.streaming.api.windowing.evictors.Evictor 的 evicBefore 和 evicAfter 两个方法。Flink 提供了如下三种通用的 evictor:


  • CountEvictor 保留指定数量的元素

  • DeltaEvictor 通过执行用户给定的 DeltaFunction 以及预设的 threshold,判断是否删除一个元素。

  • TimeEvictor 设定一个阈值 interval,删除所有不再 max_ts - interval 范围内的元素,其中 max_ts 是窗口内时间戳的最大值。


Evictor 是可选的方法,如果用户不选择,则默认没有。


Trigger 用来判断一个窗口是否需要被触发,每个 WindowAssigner 都自带一个默认的 Trigger,如果默认的 Trigger 不能满足你的需求,则可以自定义一个类,继承自 Trigger 即可,我们详细描述下 Trigger 的接口以及含义:


  • onElement() 每次往 window 增加一个元素的时候都会触发

  • onEventTime() 当 event-time timer 被触发的时候会调用

  • onProcessingTime() 当 processing-time timer 被触发的时候会调用

  • onMerge() 对两个 trigger 的 state 进行 merge 操作

  • clear() window 销毁的时候被调用


上面的接口中前三个会返回一个 TriggerResult,TriggerResult 有如下几种可能的选择:


  • CONTINUE 不做任何事情

  • FIRE 触发 window

  • PURGE 清空整个 window 的元素并销毁窗口

  • FIRE_AND_PURGE 触发窗口,然后销毁窗口


2.2 Time & Watermark

了解完上面的内容后,对于时间驱动的窗口,我们还有两个概念需要澄清:Time 和 Watermark。


我们知道在分布式环境中 Time 是一个很重要的概念,在 Flink 中 Time 可以分为三种 Event-Time,Processing-Time 以及 Ingestion-Time,三者的关系我们可以从下图中得知:



Event Time、Ingestion Time、Processing Time


Event-Time 表示事件发生的时间,Processing-Time 则表示处理消息的时间(墙上时间),Ingestion-Time 表示进入到系统的时间。


在 Flink 中我们可以通过下面的方式进行 Time 类型的设置


env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime); // 设置使用 ProcessingTime


了解了 Time 之后,我们还需要知道 Watermark 相关的概念。


我们可以考虑一个这样的例子:某 App 会记录用户的所有点击行为,并回传日志(在网络不好的情况下,先保存在本地,延后回传)。A 用户在 11:02 对 App 进行操作,B 用户在 11:03 操作了 App,但是 A 用户的网络不太稳定,回传日志延迟了,导致我们在服务端先接受到 B 用户 11:03 的消息,然后再接受到 A 用户 11:02 的消息,消息乱序了。


那我们怎么保证基于 event-time 的窗口在销毁的时候,已经处理完了所有的数据呢?这就是 watermark 的功能所在。watermark 会携带一个单调递增的时间戳 t,watermark(t) 表示所有时间戳不大于 t 的数据都已经到来了,未来小于等于 t 的数据不会再来,因此可以放心地触发和销毁窗口了。下图中给了一个乱序数据流中的 Watermark 例子



2.3 迟到的数据

上面的 Watermark 让我们能够应对乱序的数据,但是真实世界中我们没法得到一个完美的 Watermark 数值 — 要么没法获取到,要么耗费太大,因此实际工作中我们会使用近似 watermark — 生成 watermark(t) 之后,还有较小的概率接受到时间戳 t 之前的数据,在 Flink 中将这些数据定义为 “late elements”, 同样我们可以在 Window 中指定是允许延迟的最大时间(默认为 0),可以使用下面的代码进行设置



设置allowedLateness 之后,迟来的数据同样可以触发窗口,进行输出,利用 Flink 的 side output 机制,我们可以获取到这些迟到的数据,使用方式如下:



需要注意的是,设置了 allowedLateness 之后,迟到的数据也可能触发窗口,对于 Session window 来说,可能会对窗口进行合并,产生预期外的行为。


3. Window 内部实现

在讨论 Window 内部实现的时候,我们再通过下图回顾一下 Window 的生命周期。



每条数据过来之后,会由 WindowAssigner 分配到对应的 Window,当 Window 被触发之后,会交给 Evictor(如果没有设置 Evictor 则跳过),然后处理 UserFunction。其中 WindowAssigner,Trigger,Evictor 我们都在上面讨论过,而 UserFunction 则是用户编写的代码。


整个流程还有一个问题需要讨论:Window 中的状态存储。我们知道 Flink 是支持 Exactly Once 处理语义的,那么 Window 中的状态存储和普通的状态存储又有什么不一样的地方呢?


首先给出具体的答案:从接口上可以认为没有区别,但是每个 Window 会属于不同的 namespace,而非 Window 场景下,则都属于 VoidNamespace ,最终由 State/Checkpoint 来保证数据的 Exactly Once 语义,下面我们从 org.apache.flink.streaming.runtime.operators.windowing.WindowOperator 摘取一段代码进行阐述



从上面我们可以知道,Window 中的的元素同样是通过 State 进行维护,然后由 Checkpoint 机制保证 Exactly Once 语义。


至此,Time、Window 相关的所有内容都已经讲解完毕,主要包括为什么要有 Window; Window 中的三个核心组件:WindowAssigner、Trigger 和 Evictor;Window 中怎么处理乱序数据,乱序数据是否允许延迟,以及怎么处理迟到的数据;最后我们梳理了整个 Window 的数据流程,以及 Window 中怎么保证 Exactly Once 语义。


更多干货内容参见Apache Flink 零基础入门专题。


2019 年 7 月 19 日 08:044573

评论 3 条评论

发布
用户头像
"设置allowedLateness 之后,迟来的数据同样可以触发窗口,进行输出,利用 Flink 的 side output 机制,我们可以获取到这些迟到的数据", 这段描述有点歧义,首先,无论是否设置allowedLateness,如果配置sideOutputLateData,都可以得到迟到数据。其次,如果配置allowedLateness,那么这个时候的迟到是要考虑上allowedLateness的,具体对应代码为:
protected boolean isElementLate(StreamRecord<IN> element){
return (windowAssigner.isEventTime()) &&
(element.getTimestamp() + allowedLateness <= internalTimerService.currentWatermark());
}
也就是说,eventTime + allowedLateness 迟到的,才是迟到。
展开
2019 年 08 月 28 日 19:12
回复
用户头像
这个专题的每篇文章作者都不同,怎么订阅整个系列的文章?
2019 年 07 月 19 日 17:35
回复
感谢你对Flink零基础入门专题的关注,我们为整个系列文章建了一个专题,你可以关注这个小专题,后续更新的文章都会放到里面:https://www.infoq.cn/theme/28
2019 年 07 月 22 日 21:24
回复
没有更多了
发现更多内容

ORC格式和PARQUET格式介绍

五分钟学大数据

hive 存储 4月日更

腾讯iOS开发要达到咋样的水准?

一意孤行的程序员

flutter 职业规划 音视频 ios开发 iOS逆向

英特尔Ice Lake对于高性能计算市场意味着什么

新闻科技资讯

IPFS挖矿系统开发详情案例丨IPFS挖矿矿机源码平台

系统开发咨询1357O98O718

android面试题及答案,我的阿里春招之路分享,附面试答案

欢喜学安卓

android 程序员 面试 移动开发

产业级项目实战配合技术讲解,百度零门槛AI开发实训营重磅开营

百度大脑

百度 AI

手机淘宝轻店业务 Serverless 研发模式升级实践

Serverless Devs

阿里云 Serverless 云原生 淘宝

数字化转型:打破孤岛以提高数据安全性

龙归科技

数字化

华为云薛浩:走进视频“新时代”

华为云开发者社区

云原生 视频 华为云 vr 图形处理

工作三年,小胖连 HashMap 源码都没读过?真的菜!

JavaFish

扩容 hashmap 源码剖析 HashMap底层原理 加载因子

gdb调试工具使用

正向成长

gdb

【全网首发】2021 年从iOS初级到大牛,涵盖大部分iOS开发知识体系,不会没收藏吧!

一意孤行的程序员

swift ios开发 面试数据结构与算法 底层应用开发 知识分享

时间很贵,有趣才对

小天同学

读书笔记 读书感悟 好书推荐 有趣 4月日更

Rust从0到1-代码组织-Packages和Crates

rust Package crate

apk优化,996页阿里Android面试真题解析火爆全网,附面试答案

欢喜学安卓

android 程序员 面试 移动开发

面试4轮字节Java研发岗,最终拿下2-1Offer(原题复盘)

Java架构追梦

Java 字节跳动 面试 面试经历 面试题总结

2021金三银四最全大厂面试题复盘总结,刷完五月进大厂拿35K没问题(Java岗)

Crud的程序员

Java 架构 java程序员

万字长文,38 图爆肝 Redis 基础!

JavaFish

redis 数据结构 集合 哈希表 跳表

阿里P8带你学习:一次线上服务高 CPU 占用优化实践

学Java关注我

Java 编程 架构 程序人生 软件架构

云洲链硬核支撑!济南标识解析二级节点解析量全国第一

浪潮云

云计算

独家对话阿里云函数计算负责人不瞋:你所不知道的 Serverless

阿里巴巴云原生

Serverless 容器 微服务 开发者 云原生

不忘初心,中级领导力修炼

IT民工大叔

领导力 管理

Spring Cloud Gateway 和Webflux 请求参数非法字符处理

a1vin-tian

Java Spring Cloud SpringcloudGateway

浅谈BSS3.0产品“守成”之策中 • 业务提升篇

鲸品堂

系统架构 性能调优

FILPool云算力挖矿系统开发源码案例

系统开发咨询1357O98O718

Redis的AOF方案(Redis持久化)

大数据技术指南

redis 4月日更

苦难中开花|靠谱点评

无量靠谱

重读《重构2》- 以查询取代临时变量

顿晓

重构 4月日更

Spark内存管理与调优

小舰

4月日更

YouTube如何下载1080P的高清视频带声音?5种方法可以搞定

右手牵

下载 视频 youtube

随机而转 当机而动|靠谱点评

无量靠谱

Apache Flink零基础入门(五):流处理核心组件Time&Window深度解析-InfoQ