当前位置: 首页 > news >正文

Flink之窗口触发机制及自定义Trigger的使用

1 窗口触发机制

窗口计算的触发机制都是由Trigger类决定的,Flink中为各类内置的WindowsAssigner都设计了对应的默认Trigger. 层次结构如下:
  • Trigger
  • ProcessingTimeoutTrigger
  • EventTimeTrigger
  • CountTrigger
  • DeltaTrigger
  • NeverTrigger in GlobalWindows
  • ContinuousEventTimeTrigger
  • PurgingTrigger
  • ContinuousProcessingTimeTrigger
  • ProcessingTimeTrigger
通常情况下是不需要自己重写Trigger的,使用Flink内置的就可以,除非特殊业务特殊需求.
1.1 源码解析

EventTimeTrigger源码说明如何触发窗口计算,在EventTimeTrigger源码中只需要关注onElementonEventTime两个方法即可,源码内容如下:

@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

    注释中写明这个方法是基于数据进行驱动的,也就是说只有数据到达时才会执行这个方法,每一个窗口都有自己的startTimeendTime,也就是窗口的范围,判断条件中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 代码实现

通常Flink内置的Trigger都可以满足数据处理需求,往往在实际开发中可能会存在特殊的业务需求,这时用户可以自定义Trigger,以达到控制窗口触发计算的规则. 可以仿照EventTimeTrigger来构建一个自定义Trigger,只需要将其中的部分代码简单进行修改,并在onElement方法中添加自定的触发逻辑即可.
  • 自定义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年将迎来变革&#xff0c;智能家居趋势不仅会影响我们的生活空间&#xff0c;还会提高我们的生活质量&#xff0c;让我们有更多时间享受属于自己的时光。 2024年智能家居新趋势 趋势一&#xff1a;多功能科技 2024年预示着多功能技术的趋势&#xff0c;创新将成为焦点。混…...

机器学习 | Python实现GA-XGBoost遗传算法优化极限梯度提升树特征分类模型调参

机器学习 | Python实现GA-XGBoost遗传算法优化极限梯度提升树特征分类 目录 机器学习 | Python实现GA-XGBoost遗传算法优化极限梯度提升树特征分类基本介绍模型描述程序设计参考资料基本介绍 XGBoost的核心算法思想基本就是: 不断地添加树,不断地进行特征分裂来生长一棵树,每…...

手部关键点检测3:Pytorch实现手部关键点检测(手部姿势估计)含训练代码和数据集

手部关键点检测3&#xff1a;Pytorch实现手部关键点检测(手部姿势估计)含训练代码和数据集 目录 手部关键点检测3&#xff1a;Pytorch实现手部关键点检测(手部姿势估计)含训练代码和数据集 1. 前言 2.手部关键点检测(手部姿势估计)方法 (1)Top-Down(自上而下)方法 (2)Bot…...

服务日志性能调优,由log引出的巨坑

只有被线上服务问题毒打过的人才明白日志有多重要&#xff01; 谁赞成&#xff0c;谁反对&#xff1f;如果你深有同感&#xff0c;那恭喜你是个社会人了&#xff1a;&#xff09; 日志对程序的重要性不言而喻&#xff0c;轻巧、简单、无需费脑&#xff0c;程序代码中随处可见…...

【VR】【Unity】如何调整Quest2的隐藏系统时间日期

【背景】 网络虽然OK&#xff0c;但是Oculus Quest要连上商店还必须调整好系统时间&#xff0c;不过在Quest系统中&#xff0c;时间对用户是不可见的&#xff0c;本篇介绍调整的方法。 【方法】 打开SideQuest&#xff0c;没有的话先去下载一个。打开后先登录&#xff0c;如…...

C++之设计模式

C23种设计模式 https://blog.csdn.net/qq_40309341/article/details/120318957 设计模式可以同时使用多个。在软件开发中&#xff0c;通常会根据需求和问题的复杂性&#xff0c;结合多种设计模式来构建应用程序&#xff0c;以提高代码的可维护性、可扩展性和重用性。不同的设计…...

Django ORM查询

文章目录 1 增 -- 向表内插入一条数据2 删 -- 删除表内数据&#xff08;物理删除&#xff09;3 改 -- update操作更新某条数据4 查 -- 基本的表查询&#xff08;包括多表、跨表、子查询、联表查询&#xff09;4.1 基本查询4.2 双下划线查询条件4.3 逻辑查询&#xff1a;or、and…...

如何在CentOS 7中卸载Python 2.7,并安装3.X

Python是一种常用的编程语言&#xff0c;但是如果您不需要在服务器上使用Python 2.7&#xff0c;那么本文将详细介绍如何在CentOS 7上卸载Python 2.7。 一、检查Python版本 在卸载Python 2.7之前&#xff0c;必须检查系统上的Python版本。 在终端中执行以下命令&#xff1a;…...

10.17七段数码管单个多个(部分)

单个数码管的实现 第一种方式 一端并接称为位码&#xff1b;一端分别接收电平信号以控制灯的亮灭&#xff0c;称为段码 8421BCD码转七段数码管段码是将BCD码表示的十进制数转换成七段LED数码管的7个驱动段码&#xff0c; 段码就是LED灯的信号 a为1表示没用到a&#xff0c;a为…...

linux静态库与动态库

库是一种可执行的二进制文件&#xff0c;是编译好的代码。使用库可以提高开发效率。在Linux 下有静态库和动态库。   静态库在程序编译的时候会被链接到目标代码里面。所以程序在运行的时候不再需要静态库了。因此编译出来的体积就比较大。以 lib 开头&#xff0c;以.a 结尾。…...

LeetCode 面试题 10.03. 搜索旋转数组

文章目录 一、题目二、C# 题解 一、题目 搜索旋转数组。给定一个排序后的数组&#xff0c;包含n个整数&#xff0c;但这个数组已被旋转过很多次了&#xff0c;次数不详。请编写代码找出数组中的某个元素&#xff0c;假设数组元素原先是按升序排列的。若有多个相同元素&#xff…...

SpringCloudSleuth异步线程支持和传递

场景 在使用Sleuth做链路跟踪时&#xff0c;默认情况下异步线程会断链&#xff0c;需要进行代码调整支持。 调整内容 方式一 使用Async实现异步线程 开启异步线程池 EnableAsync SpringBootApplication public class LizzApplication {public static void main(String[] a…...

如何使用 Disco 将黑白照片彩色化

Disco 是一个基于视觉语言模型&#xff08;LLM&#xff09;的图像彩色化工具。它使用 LLM 来生成彩色图像&#xff0c;这些图像与原始黑白图像相似。 本文将介绍如何使用 Disco 将黑白照片彩色化。 使用 Disco 提供了一个简单的在线演示&#xff0c;可以用于测试模型。 访问…...

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款好用的在线流程图软件推荐!

随着互联网技术和基础设施的发展&#xff0c;人们能用上比过去更加稳定的网络&#xff0c;因此在使用各类工具软件时&#xff0c;越来越倾向于选择在线工具&#xff0c;或是推出了网页版的应用。 就流程图软件而言&#xff0c;过去想要绘制流程图&#xff0c;我们得在电脑上安…...

剑指Offer || 044.在每个树行中找最大值

题目 给定一棵二叉树的根节点 root &#xff0c;请找出该二叉树中每一层的最大值。 示例1&#xff1a; 输入: root [1,3,2,5,3,null,9] 输出: [1,3,9] 解释:1/ \3 2/ \ \ 5 3 9 示例2&#xff1a; 输入: root [1,2,3] 输出: [1,3] 解释:1/ \2 3示例3&#xff…...

ESP32网络开发实例-UDP数据发送与接收

UDP数据发送与接收 文章目录 UDP数据发送与接收1、UDP简单介绍2、软件准备3、硬件准备4、代码实现本文将详细介绍在Arduino开发环境中,如何实现ESP32通过UDP协议进行数据发送与接收。 1、UDP简单介绍 用户数据报协议 (UDP) 是一种跨互联网使用的通信协议,用于对时间敏感的传…...

液压自动化成套设备比例阀放大器

液压电气成套设备的比例阀放大器是一种电子控制设备&#xff0c;用于控制液压动力系统中的液压比例阀1。 比例阀放大器通常采用电子信号进行控制&#xff0c;以控制比例阀的开度和流量&#xff0c;以实现液压系统的可靠控制。比例阀放大器主要由以下组成部分&#xff1a; 驱动…...

专业144,总分440+,上岸西北工业大学827西工大信号与系统考研经验分享

我的初试备考从4月末&#xff0c;持续到初试前&#xff0c;这中间没有中断。 总的时间分配上&#xff0c;是数学>专业课>英语>政治&#xff0c;虽然大家可支配时间和基础千差万别&#xff0c;但是这么分配是没错的。 数学 时间安排&#xff1a;3月-7月&#xff1a;…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文全面剖析RNN核心原理&#xff0c;深入讲解梯度消失/爆炸问题&#xff0c;并通过LSTM/GRU结构实现解决方案&#xff0c;提供时间序列预测和文本生成…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...