Flink之窗口触发机制及自定义Trigger的使用
1 窗口触发机制
- Trigger
- ProcessingTimeoutTrigger
- EventTimeTrigger
- CountTrigger
- DeltaTrigger
- NeverTrigger in GlobalWindows
- ContinuousEventTimeTrigger
- PurgingTrigger
- ContinuousProcessingTimeTrigger
- ProcessingTimeTrigger
1.1 源码解析
以EventTimeTrigger源码说明如何触发窗口计算,在EventTimeTrigger源码中只需要关注onElement和onEventTime两个方法即可,源码内容如下:
@PublicEvolving
public class EventTimeTrigger extends Trigger<Object, TimeWindow> {private static final long serialVersionUID = 1L;private EventTimeTrigger() {}// 基于数据驱动的方法@Overridepublic TriggerResult onElement(Object element, long timestamp, TimeWindow window, TriggerContext ctx)throws Exception {// 判断当前watermark是否大于等于窗口的最大时间if (window.maxTimestamp() <= ctx.getCurrentWatermark()) {// if the watermark is already past the window fire immediately// 如果大于等于窗口的最大时间触发计算return TriggerResult.FIRE;} else {// 小于窗口的最大时间首先注册定时器ctx.registerEventTimeTimer(window.maxTimestamp());// 然后等待数据继续输入,不触发计算return TriggerResult.CONTINUE;}}// 基于事件时间定时器驱动的方法@Overridepublic TriggerResult onEventTime(long time, TimeWindow window, TriggerContext ctx) {// 根据不断发送来的watermark判断是否触发计算return time == window.maxTimestamp() ? TriggerResult.FIRE : TriggerResult.CONTINUE;}// ...
}
源码中将不需要的关注的代码都已省略
-
onElement
注释中写明这个方法是基于数据进行驱动的,也就是说只有数据到达时才会执行这个方法,每一个窗口都有自己的
startTime和endTime,也就是窗口的范围,判断条件中window.maxTimestamp()获取的就是当前窗口的endTime,如果当前watermark超出当前窗口的endTime就会触发这个窗口计算,TriggerResult.FIRE表示的就是窗口开始计算,如果当前watermark小于endTime就不会触发窗口计算这个窗口会继续等待数据输入,也就是TriggerResult.CONTINUE方法. -
onEventTime
onElement是由数据驱动的,但是Flink的实际数据处理过程是存在没有数据发送到当前窗口,但是会有watermark源源不断的发送到当前窗口的情况,在多并行度的执行条件下就会发生这种情况.在onEventTime方法中如果上游发送过来的watermark等于当前窗口的endTime就会执行TriggerResult.FIRE否则还是执行TriggerResult.CONTINUE.
Trigger的触发机制就是这样,其他的CountTrigger等大致逻辑基本是一样的,了解清楚源码中这两个方法的作用很容易理解.
1.2 代码实现
-
自定义Trigger
/*** 这里首先需要继承Trigger类,并将<Object, TimeWindow>中的Object修改成自己需要的数据类型,这段代码中需要根据UserEvent2中的数据* 来控制触发窗口计算的条件,所以将Object修改成UserEvent2**/ public class CustomTrigger extends Trigger<UserEvent2, TimeWindow> {public CustomTrigger() {}// 通过修改onElement方法中窗口计算的触发逻辑实现自定义方式@Overridepublic TriggerResult onElement(// 这里也要将原有的Object类型修改成上面的UserEvent2UserEvent2 element, long timestamp, TimeWindow window, TriggerContext ctx)throws Exception {// 原有的判断逻辑不动,这个是为了便捷,判断逻辑可以根据实际需求进行修改,或者如同下面中添加一个新的触发逻辑if (window.maxTimestamp() <= ctx.getCurrentWatermark()) {return TriggerResult.FIRE;// 这里增加一个判断逻辑,当用户行为时间为2700的时候也触发计算} else if (element.getTime().equals("2700")) {return TriggerResult.FIRE;// 原有的判断逻辑不动} else {ctx.registerEventTimeTimer(window.maxTimestamp());return TriggerResult.CONTINUE;}}@Overridepublic TriggerResult onEventTime(long time, TimeWindow window, TriggerContext ctx) {return time == window.maxTimestamp() ? TriggerResult.FIRE : TriggerResult.CONTINUE;}@Overridepublic TriggerResult onProcessingTime(long time, TimeWindow window, TriggerContext ctx)throws Exception {return TriggerResult.CONTINUE;}@Overridepublic void clear(TimeWindow window, TriggerContext ctx) throws Exception {ctx.deleteEventTimeTimer(window.maxTimestamp());}@Overridepublic boolean canMerge() {return true;}@Overridepublic void onMerge(TimeWindow window, OnMergeContext ctx) {long windowMaxTimestamp = window.maxTimestamp();if (windowMaxTimestamp > ctx.getCurrentWatermark()) {ctx.registerEventTimeTimer(windowMaxTimestamp);}}// 将toString中俄返回值根据用户的需要进行修改@Overridepublic String toString() {return "CustomTrigger()";}// 将返回值更改成创建的自定义Trigger类public static CustomTrigger create() {return new CustomTrigger();} } -
业务代码
// ... SingleOutputStreamOperator<UserEvent2> windowedStream = keyedStream.window(TumblingEventTimeWindows.of(Time.seconds(10))) // 设置滚动窗口大小为10s.trigger(new CustomTrigger()) // 传入自定义的Trigger类.allowedLateness(Time.seconds(2)) // 允许迟到数据迟到时间2s,同watermark中的forBoundedOutOfOrderness功能类似.sideOutputLateData(lateData) // 将迟到数据进行测流输出.max("time");// 获取用户行为发生事件最大的这条数据 // ...上面这段业务代码中设置的滚动窗口的大小为
10s,正常来说只有满足end - start = 10000的时候才会触发窗口计算,但是在自定义Trigger中指定了当数据中时间为2700的时候也触发窗口计算,在时间为2700的数据没到达时候还会按照原有的逻辑触发窗口计算,但是只要2700的数据到达,不管时候达到TumblingEventTimeWindows.of(Time.seconds(10))这个条件,都会触发窗口计算.
相关文章:
Flink之窗口触发机制及自定义Trigger的使用
1 窗口触发机制 窗口计算的触发机制都是由Trigger类决定的,Flink中为各类内置的WindowsAssigner都设计了对应的默认Trigger. 层次结构如下: Trigger ProcessingTimeoutTriggerEventTimeTriggerCountTriggerDeltaTriggerNeverTrigger in GlobalWindowsContinuousEventTimeTrigge…...
蓝牙资讯|2024年智能家居新趋势,蓝牙助力智能家居发展
2024年将迎来变革,智能家居趋势不仅会影响我们的生活空间,还会提高我们的生活质量,让我们有更多时间享受属于自己的时光。 2024年智能家居新趋势 趋势一:多功能科技 2024年预示着多功能技术的趋势,创新将成为焦点。混…...
机器学习 | Python实现GA-XGBoost遗传算法优化极限梯度提升树特征分类模型调参
机器学习 | Python实现GA-XGBoost遗传算法优化极限梯度提升树特征分类 目录 机器学习 | Python实现GA-XGBoost遗传算法优化极限梯度提升树特征分类基本介绍模型描述程序设计参考资料基本介绍 XGBoost的核心算法思想基本就是: 不断地添加树,不断地进行特征分裂来生长一棵树,每…...
手部关键点检测3:Pytorch实现手部关键点检测(手部姿势估计)含训练代码和数据集
手部关键点检测3:Pytorch实现手部关键点检测(手部姿势估计)含训练代码和数据集 目录 手部关键点检测3:Pytorch实现手部关键点检测(手部姿势估计)含训练代码和数据集 1. 前言 2.手部关键点检测(手部姿势估计)方法 (1)Top-Down(自上而下)方法 (2)Bot…...
服务日志性能调优,由log引出的巨坑
只有被线上服务问题毒打过的人才明白日志有多重要! 谁赞成,谁反对?如果你深有同感,那恭喜你是个社会人了:) 日志对程序的重要性不言而喻,轻巧、简单、无需费脑,程序代码中随处可见…...
【VR】【Unity】如何调整Quest2的隐藏系统时间日期
【背景】 网络虽然OK,但是Oculus Quest要连上商店还必须调整好系统时间,不过在Quest系统中,时间对用户是不可见的,本篇介绍调整的方法。 【方法】 打开SideQuest,没有的话先去下载一个。打开后先登录,如…...
C++之设计模式
C23种设计模式 https://blog.csdn.net/qq_40309341/article/details/120318957 设计模式可以同时使用多个。在软件开发中,通常会根据需求和问题的复杂性,结合多种设计模式来构建应用程序,以提高代码的可维护性、可扩展性和重用性。不同的设计…...
Django ORM查询
文章目录 1 增 -- 向表内插入一条数据2 删 -- 删除表内数据(物理删除)3 改 -- update操作更新某条数据4 查 -- 基本的表查询(包括多表、跨表、子查询、联表查询)4.1 基本查询4.2 双下划线查询条件4.3 逻辑查询:or、and…...
如何在CentOS 7中卸载Python 2.7,并安装3.X
Python是一种常用的编程语言,但是如果您不需要在服务器上使用Python 2.7,那么本文将详细介绍如何在CentOS 7上卸载Python 2.7。 一、检查Python版本 在卸载Python 2.7之前,必须检查系统上的Python版本。 在终端中执行以下命令:…...
10.17七段数码管单个多个(部分)
单个数码管的实现 第一种方式 一端并接称为位码;一端分别接收电平信号以控制灯的亮灭,称为段码 8421BCD码转七段数码管段码是将BCD码表示的十进制数转换成七段LED数码管的7个驱动段码, 段码就是LED灯的信号 a为1表示没用到a,a为…...
linux静态库与动态库
库是一种可执行的二进制文件,是编译好的代码。使用库可以提高开发效率。在Linux 下有静态库和动态库。 静态库在程序编译的时候会被链接到目标代码里面。所以程序在运行的时候不再需要静态库了。因此编译出来的体积就比较大。以 lib 开头,以.a 结尾。…...
LeetCode 面试题 10.03. 搜索旋转数组
文章目录 一、题目二、C# 题解 一、题目 搜索旋转数组。给定一个排序后的数组,包含n个整数,但这个数组已被旋转过很多次了,次数不详。请编写代码找出数组中的某个元素,假设数组元素原先是按升序排列的。若有多个相同元素ÿ…...
SpringCloudSleuth异步线程支持和传递
场景 在使用Sleuth做链路跟踪时,默认情况下异步线程会断链,需要进行代码调整支持。 调整内容 方式一 使用Async实现异步线程 开启异步线程池 EnableAsync SpringBootApplication public class LizzApplication {public static void main(String[] a…...
如何使用 Disco 将黑白照片彩色化
Disco 是一个基于视觉语言模型(LLM)的图像彩色化工具。它使用 LLM 来生成彩色图像,这些图像与原始黑白图像相似。 本文将介绍如何使用 Disco 将黑白照片彩色化。 使用 Disco 提供了一个简单的在线演示,可以用于测试模型。 访问…...
ChatGPT AIGC 制作大屏可视化分析案例
第一部分提示词prompt: 商品 价格 p1 13 p2 41 p3 42 p4 53 p5 19 p6 28 p7 92 p8 62 城市 销量 北京 69 上海 13 南京 18 武汉 66 成都 70 你现在是一名非常专业的数据分析师,请结合上述数据完成下列几件事情 1:第一部分数…...
2023年9款好用的在线流程图软件推荐!
随着互联网技术和基础设施的发展,人们能用上比过去更加稳定的网络,因此在使用各类工具软件时,越来越倾向于选择在线工具,或是推出了网页版的应用。 就流程图软件而言,过去想要绘制流程图,我们得在电脑上安…...
剑指Offer || 044.在每个树行中找最大值
题目 给定一棵二叉树的根节点 root ,请找出该二叉树中每一层的最大值。 示例1: 输入: root [1,3,2,5,3,null,9] 输出: [1,3,9] 解释:1/ \3 2/ \ \ 5 3 9 示例2: 输入: root [1,2,3] 输出: [1,3] 解释:1/ \2 3示例3ÿ…...
ESP32网络开发实例-UDP数据发送与接收
UDP数据发送与接收 文章目录 UDP数据发送与接收1、UDP简单介绍2、软件准备3、硬件准备4、代码实现本文将详细介绍在Arduino开发环境中,如何实现ESP32通过UDP协议进行数据发送与接收。 1、UDP简单介绍 用户数据报协议 (UDP) 是一种跨互联网使用的通信协议,用于对时间敏感的传…...
液压自动化成套设备比例阀放大器
液压电气成套设备的比例阀放大器是一种电子控制设备,用于控制液压动力系统中的液压比例阀1。 比例阀放大器通常采用电子信号进行控制,以控制比例阀的开度和流量,以实现液压系统的可靠控制。比例阀放大器主要由以下组成部分: 驱动…...
专业144,总分440+,上岸西北工业大学827西工大信号与系统考研经验分享
我的初试备考从4月末,持续到初试前,这中间没有中断。 总的时间分配上,是数学>专业课>英语>政治,虽然大家可支配时间和基础千差万别,但是这么分配是没错的。 数学 时间安排:3月-7月:…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能
指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...
加密通信 + 行为分析:运营商行业安全防御体系重构
在数字经济蓬勃发展的时代,运营商作为信息通信网络的核心枢纽,承载着海量用户数据与关键业务传输,其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级,传统安全防护体系逐渐暴露出局限性&a…...
