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

Flink移除器Evictor

前言

在 Flink 窗口计算模型中,数据被 WindowAssigner 划分到对应的窗口后,再经过触发器 Trigger 判断窗口是否要 fire 计算,如果窗口要计算,会把数据丢给移除器 Evictor,Evictor 可以先移除部分元素再交给 ProcessFunction 处理,也可以等 ProcessFunction 处理完成后再移除数据。

认识Evictor

Flink中所有的移除器都是org.apache.flink.streaming.api.windowing.evictors.Evictor的子类

public interface Evictor<T, W extends Window> extends Serializable {void evictBefore(Iterable<TimestampedValue<T>> var1, int var2, W var3, EvictorContext var4);void evictAfter(Iterable<TimestampedValue<T>> var1, int var2, W var3, EvictorContext var4);public interface EvictorContext {long getCurrentProcessingTime();MetricGroup getMetricGroup();long getCurrentWatermark();}
}

Evictor定义了两个方法:

  • evictBefore ProcessFunction处理前调用,用于移除无须计算的元素
  • evictAfter ProcessFunction处理后调用

内置的Evictor

Flink内置了三个Evictor,当这些Evictor不满足业务场景时,也可以自定义Evictor。

1、TimeEvictor

给定一个时间窗口大小,仅保留该时间窗口范围内的元素,对于超过了窗口时间范围的元素,会一律移除。

public class TimeEvictor<W extends Window> implements Evictor<Object, W> {private static final long serialVersionUID = 1L;private final long windowSize;private final boolean doEvictAfter;public TimeEvictor(long windowSize) {this.windowSize = windowSize;this.doEvictAfter = false;}public TimeEvictor(long windowSize, boolean doEvictAfter) {this.windowSize = windowSize;this.doEvictAfter = doEvictAfter;}public void evictBefore(Iterable<TimestampedValue<Object>> elements, int size, W window, Evictor.EvictorContext ctx) {if (!this.doEvictAfter) {this.evict(elements, size, ctx);}}public void evictAfter(Iterable<TimestampedValue<Object>> elements, int size, W window, Evictor.EvictorContext ctx) {if (this.doEvictAfter) {this.evict(elements, size, ctx);}}private void evict(Iterable<TimestampedValue<Object>> elements, int size, Evictor.EvictorContext ctx) {if (this.hasTimestamp(elements)) {long currentTime = this.getMaxTimestamp(elements);long evictCutoff = currentTime - this.windowSize;Iterator<TimestampedValue<Object>> iterator = elements.iterator();while(iterator.hasNext()) {TimestampedValue<Object> record = (TimestampedValue)iterator.next();if (record.getTimestamp() <= evictCutoff) {iterator.remove();}}}}
}

2、DeltaEvictor

给定一个 double 阈值和一个差值计算函数 DeltaFunction,依次计算窗口内元素和最后一个元素的差值 delta,所有 delta 超过阈值的元素都会被移除。

public class DeltaEvictor<T, W extends Window> implements Evictor<T, W> {private static final long serialVersionUID = 1L;DeltaFunction<T> deltaFunction;private double threshold;private final boolean doEvictAfter;private DeltaEvictor(double threshold, DeltaFunction<T> deltaFunction) {this.deltaFunction = deltaFunction;this.threshold = threshold;this.doEvictAfter = false;}private DeltaEvictor(double threshold, DeltaFunction<T> deltaFunction, boolean doEvictAfter) {this.deltaFunction = deltaFunction;this.threshold = threshold;this.doEvictAfter = doEvictAfter;}public void evictBefore(Iterable<TimestampedValue<T>> elements, int size, W window, Evictor.EvictorContext ctx) {if (!this.doEvictAfter) {this.evict(elements, size, ctx);}}public void evictAfter(Iterable<TimestampedValue<T>> elements, int size, W window, Evictor.EvictorContext ctx) {if (this.doEvictAfter) {this.evict(elements, size, ctx);}}private void evict(Iterable<TimestampedValue<T>> elements, int size, Evictor.EvictorContext ctx) {TimestampedValue<T> lastElement = (TimestampedValue)Iterables.getLast(elements);Iterator<TimestampedValue<T>> iterator = elements.iterator();while(iterator.hasNext()) {TimestampedValue<T> element = (TimestampedValue)iterator.next();if (this.deltaFunction.getDelta(element.getValue(), lastElement.getValue()) >= this.threshold) {iterator.remove();}}}
}

3、CountEvictor

给定一个 maxCount,依次遍历窗口内的元素,数量超过 maxCount 后的所有元素全部移除。

public class CountEvictor<W extends Window> implements Evictor<Object, W> {private static final long serialVersionUID = 1L;private final long maxCount;private final boolean doEvictAfter;private CountEvictor(long count, boolean doEvictAfter) {this.maxCount = count;this.doEvictAfter = doEvictAfter;}private CountEvictor(long count) {this.maxCount = count;this.doEvictAfter = false;}public void evictBefore(Iterable<TimestampedValue<Object>> elements, int size, W window, Evictor.EvictorContext ctx) {if (!this.doEvictAfter) {this.evict(elements, size, ctx);}}public void evictAfter(Iterable<TimestampedValue<Object>> elements, int size, W window, Evictor.EvictorContext ctx) {if (this.doEvictAfter) {this.evict(elements, size, ctx);}}private void evict(Iterable<TimestampedValue<Object>> elements, int size, Evictor.EvictorContext ctx) {if ((long)size > this.maxCount) {int evictedCount = 0;Iterator<TimestampedValue<Object>> iterator = elements.iterator();while(iterator.hasNext()) {iterator.next();++evictedCount;if ((long)evictedCount > (long)size - this.maxCount) {break;}iterator.remove();}}}
}

自定义Evictor

实现org.apache.flink.streaming.api.windowing.evictors.Evictor接口即可自定义 Evictor,泛型要注意,第一个是元素类型,第二个是窗口类型。

举个例子,我们定义一个 Evictor,它在 ProcessFunction 计算前把窗口内所有的奇数全部移除掉,只保留偶数。

public static class MyEvictor implements Evictor<Integer, GlobalWindow> {@Overridepublic void evictBefore(Iterable<TimestampedValue<Integer>> iterable, int i, GlobalWindow globalWindow, EvictorContext evictorContext) {Iterator<TimestampedValue<Integer>> iterator = iterable.iterator();while (iterator.hasNext()) {TimestampedValue<Integer> value = iterator.next();if (value.getValue() % 2 != 0) {iterator.remove();}}}@Overridepublic void evictAfter(Iterable<TimestampedValue<Integer>> iterable, int i, GlobalWindow globalWindow, EvictorContext evictorContext) {}
}

编写一个简单的 Flink 作业验证一下我们自定义的 Evictor,数据源手动指定为数字1到6,统一分配到 GlobalWindow 窗口,Trigger 元素等于6个就出发计算,最终输出窗口内的元素

public static void main(String[] args) throws Exception {StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();environment.fromElements(1, 2, 3, 4, 5, 6).windowAll(GlobalWindows.create()).trigger(CountTrigger.of(6)).evictor(new MyEvictor()).process(new ProcessAllWindowFunction<Integer, Object, GlobalWindow>() {@Overridepublic void process(ProcessAllWindowFunction<Integer, Object, GlobalWindow>.Context context, Iterable<Integer> iterable, Collector<Object> collector) throws Exception {String elements = StringUtils.joinWith(",", iterable);System.err.println(elements);}});environment.execute();
}

运行Flink作业,控制台输出[2, 4, 6],奇数在计算前就被移除掉了。

尾巴

Flink 的 Evictor 主要用于在窗口计算过程中,对窗口中的元素进行筛选和剔除。通过定义特定的 Evictor 策略,可以有效地控制窗口内数据的留存和输出。 Evictor 有助于提高数据处理的准确性和效率。它能够根据业务需求,如时间、数据特征等,去除不符合条件的数据,从而使窗口的计算结果更具针对性和可靠性。

相关文章:

Flink移除器Evictor

前言 在 Flink 窗口计算模型中&#xff0c;数据被 WindowAssigner 划分到对应的窗口后&#xff0c;再经过触发器 Trigger 判断窗口是否要 fire 计算&#xff0c;如果窗口要计算&#xff0c;会把数据丢给移除器 Evictor&#xff0c;Evictor 可以先移除部分元素再交给 ProcessFu…...

R语言实现多元线性回归高杠杠点,离群点分析

14a set.seed(1) x1 = runif(100) x2 = 0.5 * x1 + rnorm(100)/...

overfrp内网穿透:使用域名将内网http/https服务暴露到公网

项目地址&#xff1a;https://github.com/sometiny/overfrp 使用overfrp部署穿透服务器&#xff0c;绑定域名后&#xff0c;可使用域名访问内网的http/https服务。 用例中穿透服务器和内网机器之间的访问全链路加密&#xff0c;具有ssh2相当的安全级别。&#xff01;&#xf…...

springboot034在线商城系统设计与开发-代码(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;ONLY在线商城系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本ONLY在线商城系统…...

什么是第三范式(3NF)?为什么要遵守第三范式?

第三范式&#xff08;Third Normal Form, 3NF&#xff09;是数据库设计中的一个重要概念&#xff0c;它是对关系型数据库规范化的一种标准。 在数据库设计中&#xff0c;通过将数据表按照一定的规则进行分解&#xff0c;可以减少数据冗余和提高数据的一致性。 3NF 是建立在第…...

大数据比对,shell脚本与hive技术结合

需求描述 从主机中获取加密数据内容&#xff0c;解密数据内容&#xff08;可能会存在json解析&#xff09;插入到另一个库中&#xff0c;比对原始库和新库的相同表数据的数据一致性内容。 数据一致性比对实现 上亿条数据&#xff0c;如何比对并发现两个表数据差异 相关流程…...

【Linux安全基线】- CentOS 7/8安全配置指南

在企业业务的生产环境中&#xff0c;Linux服务器的安全性至关重要&#xff0c;尤其是对于具有超级用户权限的root账号。滥用或被入侵后&#xff0c;可能会造成数据泄露、系统损坏等严重安全问题。为了减少这种风险&#xff0c;本文将详细介绍如何通过一系列安全措施来增强CentO…...

PDF.js的使用及其跨域问题解决

目录 一、PDF.js 简介 二、使用配置和步骤 1.引入PDF.js 2.加载PDF文件 3.渲染PDF页面 三、在Vue中使用PDF.js示例 1.安装PDF.js 2.在Vue组件中使用 四、在原生js中使用PDF.js示例 1.加载PDF文件并渲染页面 五、解决跨域问题 1.服务器配置 2.使用代理服务器 下面介…...

Linux Redis查询key与移除日常操作

维护老项目Express node 编写的后端程序、有这么一个方法、没有设置redis过期时间&#xff08;建议设置过期时间&#xff0c;毕竟登录生产服务器并不是每个人都有权限登录的&#xff01;&#xff01;&#xff01;&#xff09;。如果变动只能通过登录生产服务器、手动修改… 于…...

开源两个月,antflow后端项目全网获近100星

从六月初开源,转眼间AntFlow已经开源将近四个月了(前端比后端早了大约2个月,后端于8.18开源).(其实准备是重构以前开源版本.前年的时候我们已经将Vue2版的流程设计器开源了.后来由于疫情原因,没有再继续持续开发.)后来有一天再打开仓库的时候,发现虽然很久没有更新了,但是不断有…...

设计模式——工厂方法模式(2)抽象工厂模式(3)

一、写在前面 创建型模式 单例模式工厂方法模式抽象工厂模式原型模式建造者模式 结构型模式行为型模式工厂方法模式和抽象工厂模式都属于工厂模式&#xff0c;所以放在一起介绍了 二、介绍 为什么要工厂模式&#xff1f;工厂就像一个黑盒一样&#xff0c;所以用工厂模式来创…...

简单聊聊System V下的IPC + 内核是如何管理该IPC

文章目录 前言&#xff1a;&#x1f383;消息队列&#xff1a;1. **消息队列的基本概念**2. **消息队列的特点**3. **常见的消息队列操作&#xff08;Linux IPC&#xff09;****1) msgget&#xff1a;创建或获取消息队列****2) msgsnd&#xff1a;发送消息****3) msgrcv&#x…...

【WRF工具】服务器上安装convert_geotiff

【WRF工具】服务器上安装convert_geotiff convert_geotiff简介方法1&#xff1a;下载安装包后下载convert_geotiff依赖库安装库1&#xff1a;libtiff库2&#xff1a;sqlite库3&#xff1a;curl库4&#xff1a;projcmake更新&#xff08;可选&#xff09;库5&#xff1a;geotiff…...

RPC通讯基础原理

1.RPC&#xff08;Remote Procedure Call&#xff09;概述 RPC是一种通过网络从远程计算机上调用程序的技术&#xff0c;使得构建分布式计算更加容易&#xff0c;在提供强大的远程调用能力时不损失本地调用的语义简洁性&#xff0c;提供一种透明调用机制&#xff0c;让使用者不…...

JavaScript 第18章:安全性

在JavaScript开发中&#xff0c;确保应用的安全性是非常重要的。下面我将根据你提到的几个方面来讲解如何增强Web应用程序的安全性。 XSS&#xff08;跨站脚本&#xff09;攻击防御 示例代码&#xff1a; function escapeHTML(unsafe) {return unsafe.replace(/&/g, &qu…...

基于workbox实现PWA预缓存能力

引言 Service Worker 是一项流行的技术&#xff0c;尽管在许多项目中尚未得到充分利用。基于本次项目首页加载优化的机会&#xff0c;决定尝试使用 Google 出品的 Workbox&#xff0c;以观察其优化效果。 开始 安装 项目使用 Webpack 打包&#xff0c;而 Workbox 提供了 We…...

探索Web3生态系统:社区、协议与参与者的角色

Web3代表着互联网的下一个演变阶段&#xff0c;旨在通过去中心化技术赋予用户更大的控制权和参与感。在这个新兴生态系统中&#xff0c;社区、协议和参与者扮演着不可或缺的角色&#xff0c;共同推动着Web3的建设与发展。 社区的核心作用 在Web3中&#xff0c;社区通过提供反馈…...

无人机电机故障率骤降:创新设计与六西格玛方法论双赢

项目背景 TBR-100是消费级无人机头部企业推出的主打消费级无人机&#xff0c;凭借其出色的续航能力和卓越的操控性&#xff0c;在市场上获得了广泛认可。在产品运行过程&#xff0c;用户反馈电机故障率偏高&#xff0c;尤其是在飞行一段时间后出现电机过热、损坏以及运行不稳定…...

samba禁用时拷贝服务器文件到本地的脚本

Android系统开发一般在ubuntu服务器上&#xff0c;我们办公电脑一般是windows。在将编译出来的模块push到板子上时&#xff0c;一般采用adb push 方式。 有时由于种种原因会出现服务器禁用了samba&#xff0c;导致无法直接用adb push 的情况。 下面介绍用winscp 走ssh 拷贝服…...

C#代码 串口通信晋中A2板,控制直流电机

1&#xff0c;在电脑中给晋中板中下载编译好的程序。 0x39 &#xff1a;开启电机的标识 代码&#xff1a; /********************************************************************************** **** 实验名称&#xff1a;串口通信实验 接线说明&#xff1a; 实验现象&…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

CMake 从 GitHub 下载第三方库并使用

有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...