FLink处理函数ProcessFunction、KeyedProcessFunction、ProcessWindowFunction、 ProcessAllWindowFunction
一、处理函数简介
在底层,我们可以不定义任何具体的算子(比如 map,filter,或者 window),而只是提炼出一个统一的“处理”(process)操作——它是所有转换算子的一个概括性的表达,可以自定义处理逻辑,所以这一层接口就被叫作“处理函数”(process function)。在处理函数中,我们直面的就是数据流中最基本的元素:数据事件(event)、状态(state)以及时间(time)。这就相当于对流有了完全的控制权。处理函数比较抽象,没有具体的操作,所以对于一些常见的简单应用(比如求和、开窗口)会显得有些麻烦;不过正是因为它不限定具体做什么,所以理论上我们可以做任何事情,实现所有需求。
二、几种处理函数简介
1、ProcessFunction是用于处理数据流的通用函数。它是一个抽象类,定义了处理数据流的常用方法,如processElement,onTimer等。您可以扩展ProcessFunction类并重写这些方法,以便在Flink程序中执行复杂的数据流处理逻辑。
2、KeyedProcessFunction是ProcessFunction的特殊类型,用于处理带有键的数据流。它定义了额外的方法,如getKey,context.timerService()等,用于访问数据流中每个元素的键以及在处理函数中安排定时器。
3、ProcessWindowFunction和ProcessAllWindowFunction是用于处理时间窗口的特殊函数。它们提供了一个process方法,用于在每个窗口中对数据进行处理。ProcessWindowFunction接受带有键的数据流,并且每个窗口都对应于一个键,而ProcessAllWindowFunction接受不带键的数据流,并且每个窗口都包含整个数据流。
三、处理函数详细介绍
1、基本处理函数ProcessFunction,继承AbstractRichFunction
基本处理函数提供了一个“定时服务”(TimerService),我们可以通过它访问流中的事件(event)、时间戳(timestamp)、水位线(watermark),甚至可以注册“定时事件”。而且处理函数继承了 AbstractRichFunction 抽象类,所以拥有富函数类的所有特性,同样可以访问状态(state)和其他运行时信息。此外,处理函数还可以直接将数据输出到侧输出流(side output)中。所以,处理函数是最为灵活的处理方法,可以实现各种自定义的业务逻辑;同时也是整个 DataStream API 的底层基础。
(1)使用方法
主程序中调用自定义的处理类
stream.process(new MyProcessFunction())
新建MyProcessFunction类
自定义处理函数主要继承了ProcessFunction。有两个泛型类型参数:I 表示 Input,也就是输入的数据类型;O 表示 Output,也就是处理完成之后输出的数据类型
public class MyProcessFunction extends ProcessFunction<I, O>{
//打开时处理
@Override
public void open(Configuration parameters) throws Exception {}
/**
* 用于处理元素
* value:当前流中的输入元素,也就是正在处理的数据,类型与流中数据类
* ctx:类型是 ProcessFunction 中定义的内部抽象类 Context,表示当前运行的上下文,可以获取到当前的时间戳,
* 并提供了用于查询时间和注册定时器的“定时服务”(TimerService),以及可以将数据发送到“侧输出流”(side output)的方法.output()。
* out:"收集器"(类型为 Collector),用于返回输出数据。使用方式与 flatMap算子中的收集器完全一样,直接调用 out.collect()方法就可以向下游发出一个数据。
*/
@Override
public void processElement(I value, Context ctx, Collector<O> out) throws Exception {}
//关闭时处理
@Override
public void close() throws Exception {}
}
(2)引用技术简介
上文提到的TimerService,是 Flink 关于时间和定时器的基础服务接口,包含以下六个方法:
处理函数中都可以直接访问TimerService,但是只有基于 KeyedStream 的处理函数,才能去调用注册和删除定时器的方法;
// 获取当前的处理时间
long currentProcessingTime();
// 获取当前的水位线(事件时间)
long currentWatermark();
// 注册处理时间定时器,当处理时间超过 time 时触发
void registerProcessingTimeTimer(long time);
// 注册事件时间定时器,当水位线超过 time 时触发
void registerEventTimeTimer(long time);
// 删除触发时间为 time 的处理时间定时器
void deleteProcessingTimeTimer(long time);
// 删除触发时间为 time 的处理时间定时器
void deleteEventTimeTimer(long time);
2、按键分区处理函数KeyedProcessFunction,继承AbstractRichFunction
在 Flink 程序中,为了实现数据的聚合统计,或者开窗计算之类的功能,我们一般都要先用 keyBy 算子对数据流进行“按键分区”,得到一个 KeyedStream。也就是指定一个键(key),按照它的哈希值(hash code)将数据分成不同的“组”,然后分配到不同的并行子任务上执行计算;这相当于做了一个逻辑分流的操作,从而可以充分利用并行计算的优势实时处理海量数据。
只有在 KeyedStream 中才支持使用 TimerService 设置定时器的操作。所以一般情况下,我们都是先做了 keyBy 分区之后,再去定义处理操作;代码中更加常见的处理函数是 KeyedProcessFunction,最基本的 ProcessFunction 反而出镜率没那么高。
KeyedProcessFunction 的一个特色,就是可以灵活地使用定时器。定时器(timers)是处理函数中进行时间相关操作的主要机制。在.onTimer()方法中可以实现定时处理的逻辑,而它能触发的前提,就是之前曾经注册过定时器、并且现在已经到了触发时间。注册定时器的功能,是通过上下文中提供的“定时服务”(TimerService)来实现的。
(1)使用方法
使用方法
DataStream<Tuple2<String, Long>> clickCountStream = stream
.keyBy("替换为需要分组字段")
.process(new MyProcessFunction());
自定义处理函数,需要替换输入输出类型
import org.apache.flink.streaming.api.functions.KeyedProcessFunction;
import org.apache.flink.util.Collector;
/**
* K:当前按键分区的 key 的类型
* I:输入类型
* O:输出类型
*/
public class MyProcessFunction extends KeyedProcessFunction<K, I, O> {
/**
*用来处理流中的每一个数据
* @param value
* @param ctx
* @param out
* @throws Exception
*/
@Override
public void processElement(I value, Context ctx, Collector<O> out) throws Exception {
}
/**
* 非必须方法onTimer()用来定义定时器触发时的回调操作
* 由于定时器只能在 KeyedStream 上使用,所以到了 KeyedProcessFunction 这里,我们才真正对时间有了精细的控制,定时方法.onTimer()才真正派上了用场
* 使用场景:假设你有一个流数据流,其中包含每个用户的点击数据,并且你想要对每个用户的点击数进行计数。你可以使用 KeyedProcessFunction 来实现这个功能,如下所示:
*/
@Override
public void onTimer(long timestamp, OnTimerContext ctx, Collector out) throws Exception {
super.onTimer(timestamp, ctx, out);
}
}
3、窗口处理函数ProcessWindowFunction,继承AbstractRichFunction
ProcessWindowFunction 既是处理函数又是全窗口函数。从名字上也可以推测出,它的本质似乎更倾向于“窗口函数”一些。
使用方式
DataStream<OUT> clickCountStream = clickEventStream
.keyBy(ClickEvent::getUserId)
//定义一小时窗口
.timeWindow(Time.hours(1))
.process(new MyProcessFunction());
自定义窗口函数
import org.apache.flink.streaming.api.functions.windowing.ProcessWindowFunction;
import org.apache.flink.util.Collector;
/**
* IN:输入类型
* OUT:输出类型
* KEY:数据中键 key 的类型
* W:窗口的类型,一般为TimeWindow
*/
public class MyProcessFunction extends ProcessWindowFunction<IN, OUT, KEY, W extends Window> {
/**
* KEY、IN、OUT替换成对应的类型
* context:当前窗口进行计算的上下文
*/
@Override
public void process(KEY o, Context context, Iterable<IN> elements, Collector<OUT> out) throws Exception {
}
}
4、全窗口函数
它与 ProcessWindowFunction 类似,但是它会对窗口中的所有数据进行处理,而不是仅处理触发窗口计算的数据。
使用方式
DataStream<OUT> clickCountStream = clickEventStream
.keyBy(ClickEvent::getUserId)
//定义一小时窗口
.timeWindow(Time.hours(1))
.process(new MyProcessFunction());
自定义窗口函数
import org.apache.flink.streaming.api.functions.windowing.ProcessAllWindowFunction;
import org.apache.flink.streaming.api.windowing.windows.Window;
import org.apache.flink.util.Collector;
/**
* IN:输入类型
* OUT:输出类型
* KEY:数据中键 key 的类型
* W:窗口的类型
*/
public class MyProcessFunction extends ProcessAllWindowFunction<IN, OUT, W extends Window> {
/**
* IN、OUT替换成对应的类型
* context:当前窗口进行计算的上下文
*/
@Override
public void process(Context context, Iterable<IN> elements, Collector<OUT> out) throws Exception {
}
}
FLink处理函数ProcessFunction、KeyedProcessFunction、ProcessWindowFunction、 ProcessAllWindowFunction的更多相关文章
- Flink处理函数实战之一:深入了解ProcessFunction的状态(Flink-1.10)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Flink处理函数实战之二:ProcessFunction类
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Flink处理函数实战之三:KeyedProcessFunction类
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Flink处理函数实战之四:窗口处理
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Flink处理函数实战之五:CoProcessFunction(双流处理)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- flink udaf函数
1.Flink-sql自定义UDAF函数 - 简书 (jianshu.com) 2.Flink SQL 自定义UDAF_k_wzzc的博客-CSDN博客_flink udaf 3.Flink 实践教程 ...
- flink 注册函数示例
需求 (filter): 现在有这么一个需求,统计出现在纽约的行车记录.这里我们需要进行一个过滤的操作,我们需要有个自定义的 UDF ,具体思路是,表里面有经度和维度这两个字段,通过这个可以来开发一个 ...
- 5、flink常见函数使用及自定义转换函数
代码地址:https://gitee.com/nltxwz_xxd/abc_bigdata 一.flink编程方法 获取执行环境(execution environment) 加载/创建初始数据集 对 ...
- Flink中的window、watermark和ProcessFunction
一.Flink中的window 1,window简述 window 是一种切割无限数据为有限块进行处理的手段.Window 是无限数据流处理的核心,Window 将一个无限的 stream 拆分成有 ...
- 【大数据面试】Flink 03-窗口、时间语义和水印、ProcessFunction底层API
三.窗口 1.窗口的介绍 (1)含义 将无限的流式数据切割为有限块处理,以便于聚合等操作 (2)图解 2.窗口的分类 (1)按性质分 Flink 支持三种划分窗口的方式,time.count和会话窗口 ...
随机推荐
- .NET周刊【12月第2期 2024-12-08】
国内文章 终于解决了.net在线客服系统总是被360误报的问题(对软件进行数字签名) https://www.cnblogs.com/sheng_chao/p/18581139 升讯威在线客服与营销系 ...
- 面试官:DNS解析都整不明白,敢说你懂网络?我:嘤嘤嘤!
一.写在开头 在OSI七层协议模型中应用层是距离我们最近,且日后开发使用到最多的一层,在上一篇博文中我们已经学习了应用层中的HTTP协议,在本文中我们再一起来学一下DNS.啥?DNS不是很了解?那还不 ...
- 【分享】记一次项目迁移(docker java | docker python)
项目:前端Vue3,后端Python+Java,数据库Redis+MySQL 原先部署在centos7里面的,使用的宝塔面板部署的,还算方便. 但是服务器要到期了,要将项目迁移到另外一台服务器. 另外 ...
- 关于QCustomPlot超级图表的一些冷知识点
开源的图表控件QCustomPlot很经典,作者至少是八星斗圣级别,在曲线数据展示这块性能彪悍,总结了一些容易忽略的经验要点. 可以将XY轴对调,然后形成横向的效果,无论是曲线图还是柱状图,分组图.堆 ...
- 使用MathNet.Numerics库构造矩阵并初始化时,编译器报错“this方法没有任何重载采用"1"个参数”
最近在使用MathNet.Numerics库作一些数据处理工作,构造一个矩阵并初始化时,编译器报错"this方法没有任何重载采用"1"个参数". 问题分析: 构 ...
- IM开发基础知识补课(十):大型IM系统有多难?万字长文,搞懂异地多活!
本文由公众号"水滴与银弹"号主Kaito原创分享,原题"搞懂异地多活,看这篇就够了",为使文章更好理解,有修订. 1.引言 前几天技术群里有群友问我手上有没有I ...
- .net core反射练习-简易版IOC容器实现
实现一个简易的IOC容器 先说一下简单思路,参考ServiceCollection,需要一个注册方法跟获取实例方法,同时支持构造函数注入.那么只需要一个地方存储注册接口跟该接口的继承类,以及根据类的构 ...
- 使用 NodeLocalDNS 提升集群 DNS 性能和可靠性
本文主要分享如何使用 NodeLocal DNSCache 来提升集群中的 DNS 性能以及可靠性,包括部署.使用配置以及原理分析,最终通过压测表明使用后带来了高达 50% 的性能提升. 1.背景 什 ...
- 2024新版本如何配置CLion与cubeMX开发STM32
2024新版本如何配置CLion与cubeMX开发STM32 1. 为什么我要在网上有很多教程的情况下再做一个新版 各种大佬们给出的配置教程原本很详细,但是在时间过了这么久之后已经不完全符合现在的环境 ...
- 安装Rational rose软件简单教程
安装Rational rose软件简单教程 一.下载文件 百度云盘下载链接:https://pan.baidu.com/s/1QWmTgxKlQtE5flP7dXIF5w 提取码:wjnq 二.装虚拟 ...