flink学习(7)——window
概述
窗口的长度(大小): 决定了要计算最近多长时间的数据
窗口的间隔: 决定了每隔多久计算一次
举例:每隔10min,计算最近24h的热搜词,24小时是长度,每隔10分钟是间隔。
窗口的分类
1、根据window前是否调用keyBy分为键控窗口和非键控窗口
2、根据window中参数的配置分为基于时间的,基于条数的,会话窗口
SlidingProcessingTimeWindows —— 滑动窗口,按照处理时间
TumblingProcessingTimeWindows —— 滚动窗口,按照处理时间
ProcessingTimeSessionWindows —— 会话窗口
Keyed Window --键控窗口
// Keyed Window
stream.keyBy(...) <- 按照一个Key进行分组.window(...) <- 将数据流中的元素分配到相应的窗口中[.trigger(...)] <- 指定触发器Trigger(可选)[.evictor(...)] <- 指定清除器Evictor(可选).reduce/aggregate/process/apply() <- 窗口处理函数Window Function
Non-Keyed Window
// Non-Keyed Window
stream.windowAll(...) <- 不分组,将数据流中的所有元素分配到相应的窗口中[.trigger(...)] <- 指定触发器Trigger(可选)[.evictor(...)] <- 指定清除器Evictor(可选).reduce/aggregate/process() <- 窗口处理函数Window Function
方括号([…]) 中的命令是可选的。
首先:我们要决定是否对一个DataStream按照Key进行分组,这一步必须在窗口计算之前进行。
经过keyBy的数据流将形成多组数据,下游算子的多个实例可以并行计算。
windowAll不对数据流进行分组,所有数据将发送到下游算子单个实例上。
决定是否分组之后,窗口的后续操作基本相同。
经过windowAll的算子是不分组的窗口(Non-Keyed Window),它们的原理和操作与Keyed Window类似,唯一的区别在于所有数据将发送给下游的单个实例,或者说下游算子的并行度为1。
Flink窗口的骨架结构中有两个必须的两个操作:
-
使用窗口分配器(WindowAssigner)将数据流中的元素分配到对应的窗口。
-
当满足窗口触发条件后,对窗口内的数据使用窗口处理函数(Window Function)进行处理,常用的Window Function有reduce、aggregate、process。
其他的trigger、evictor则是窗口的触发和销毁过程中的附加选项,主要面向需要更多自定义的高级编程者,如果不设置则会使用默认的配置。
基于时间的窗口
滚动窗口- TumblingWindow概念
package com.bigdata.day04;public class _01_windows {/*** 1、实时统计每个红绿灯通过的汽车数量* 2、实时统计每个红绿灯每个1分钟,统计最近1分钟通过的汽车数量 ——滚动* 3、实时统计每个红绿灯每个1分钟,统计最近2分钟通过的汽车数量 ——滑动*/public static void main(String[] args) throws Exception {//1. env-准备环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);//2. source-加载数据DataStreamSource<String> socketStream = env.socketTextStream("localhost", 8889);//3. transformation-数据处理转换socketStream.map(new MapFunction<String, Tuple2<Integer,Integer>>() {@Overridepublic Tuple2<Integer,Integer> map(String line) throws Exception {String[] words = line.split(" ");return new Tuple2<>(Integer.parseInt(words[0]),Integer.parseInt(words[1]));}}).keyBy(new KeySelector<Tuple2<Integer, Integer>, Integer>() {@Overridepublic Integer getKey(Tuple2<Integer, Integer> value) throws Exception {return value.f0;}})// 基于这个部分实现 滚动窗口 每一分钟 统计前一分钟的数据.window(TumblingProcessingTimeWindows.of(Time.minutes(1))).sum(1).print();env.execute();}
}
滑动窗口– SlidingWindow概念
package com.bigdata.day04;import org.apache.flink.api.common.RuntimeExecutionMode;
import org.apache.flink.api.common.functions.MapFunction;import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.assigners.SlidingProcessingTimeWindows;
import org.apache.flink.streaming.api.windowing.assigners.TumblingProcessingTimeWindows;
import org.apache.flink.streaming.api.windowing.assigners.WindowAssigner;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.windows.Window;/*** @基本功能:* @program:flinkProject* @author: jinnian* @create:2024-11-25 10:13:46**/
public class _01_windows {/*** 1、实时统计每个红绿灯通过的汽车数量* 2、实时统计每个红绿灯每个1分钟,统计最近1分钟通过的汽车数量 ——滚动* 3、实时统计每个红绿灯每个1分钟,统计最近2分钟通过的汽车数量 ——滑动*/public static void main(String[] args) throws Exception {//1. env-准备环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);//2. source-加载数据DataStreamSource<String> socketStream = env.socketTextStream("localhost", 8889);//3. transformation-数据处理转换socketStream.map(new MapFunction<String, Tuple2<Integer,Integer>>() {@Overridepublic Tuple2<Integer,Integer> map(String line) throws Exception {String[] words = line.split(" ");return new Tuple2<>(Integer.parseInt(words[0]),Integer.parseInt(words[1]));}}).keyBy(new KeySelector<Tuple2<Integer, Integer>, Integer>() {@Overridepublic Integer getKey(Tuple2<Integer, Integer> value) throws Exception {return value.f0;}})// 基于这一部分实现,每30秒统计前一分钟的数据,大的在前,小的在后.window(SlidingProcessingTimeWindows.of(Time.minutes(1),Time.seconds(30))).sum(1).print();//5. execute-执行env.execute();}
}
如何显示窗口时间——apply
——apply将reduce替代
kafka生产数据
package com.bigdata.day04;public class _02_kafka生产数据 {public static void main(String[] args) throws InterruptedException {// Properties 它是map的一种Properties properties = new Properties();// 设置连接kafka集群的ip和端口properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"bigdata01:9092");properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");KafkaProducer<String, String> producer = new KafkaProducer<>(properties);String[] arr = {"联通换猫","遥遥领先","恒大歌舞团","恒大足球队","郑州烂尾楼"};Random random = new Random();for (int i = 0; i < 5000; i++) {int index = random.nextInt(arr.length);ProducerRecord<String, String> record = new ProducerRecord<>("edu", arr[index]);producer.send(record);Thread.sleep(30);}}
}
flink消费数据
package com.bigdata.day04;public class _02_flink消费数据 {public static void main(String[] args) throws Exception {//1. env-准备环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);Properties properties = new Properties();properties.setProperty("bootstrap.servers", "bigdata01:9092");properties.setProperty("group.id", "gw2");FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<String>("edu",new SimpleStringSchema(),properties);DataStreamSource<String> source = env.addSource(consumer);source.map(new MapFunction<String, Tuple2<String,Integer>>() {@Overridepublic Tuple2<String,Integer> map(String value) throws Exception {return Tuple2.of(value,1);}}).keyBy(new KeySelector<Tuple2<String, Integer>, String>() {@Overridepublic String getKey(Tuple2<String, Integer> value) throws Exception {return value.f0;}}).window(SlidingProcessingTimeWindows.of(Time.minutes(1),Time.seconds(30)))//.window(TumblingProcessingTimeWindows.of(Time.seconds(30)))/****/.apply(new WindowFunction<Tuple2<String, Integer>, String, String, TimeWindow>() {@Overridepublic void apply(String key, TimeWindow window, Iterable<Tuple2<String, Integer>> input, Collector<String> out) throws Exception {StringBuilder sb = new StringBuilder();long start = window.getStart();long end = window.getEnd();String startStr = DateFormatUtils.format(start, "yyyy-MM-dd HH:mm:ss");String endStr = DateFormatUtils.format(end, "yyyy-MM-dd HH:mm:ss");int sum = 0;for (Tuple2<String, Integer> tuple2 : input) {sum +=tuple2.f1;}sb.append("开始时间:"+startStr+",").append("结束时间:"+endStr+",").append("key: "+key+ ",").append("数量:"+sum);out.collect(sb.toString());}}).print();env.execute();}
}
基于条数的窗口——countWindow
package com.bigdata.day04;public class _04_agg函数 {public static final Tuple3[] ENGLISH = new Tuple3[] {Tuple3.of("class1", "张三", 100L),Tuple3.of("class1", "李四", 40L),Tuple3.of("class1", "王五", 60L),Tuple3.of("class2", "赵六", 20L),Tuple3.of("class2", "小七", 30L),Tuple3.of("class2", "小八", 50L),};public static void main(String[] args) throws Exception {//1. env-准备环境StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);//2. source-加载数据DataStreamSource<Tuple3<String,String,Long>> dataStreamSource = env.fromElements(ENGLISH);// 此时我要获取每个班级的平均成绩// 输入数据的类型(IN)、累加器的类型(ACC)和输出数据的类型(OUT)// IN——Tuple3<String, String, Long>// ACC——Tuple3<String, Integer,Long> 第一个是班级(key)第二个是数量,第三个是总的成绩// OUT —— Tuple2<String,Double> 第一个是班级 第二个是平均成绩dataStreamSource.countWindowAll(3).aggregate(new AggregateFunction<Tuple3<String, String, Long>, Tuple3<String, Integer,Long>, Tuple2<String,Double>>() {// 初始化一个 累加器@Overridepublic Tuple3<String, Integer, Long> createAccumulator() {return Tuple3.of(null,0,0L);}// 累加器和输入的值进行累加// Tuple3<String, String, Long> value 第一个是传入的值// Tuple3<String, Integer, Long> accumulator 第二个是累加器的值@Overridepublic Tuple3<String, Integer, Long> add(Tuple3<String, String, Long> value, Tuple3<String, Integer, Long> accumulator) {return Tuple3.of(value.f0,accumulator.f1+1,accumulator.f2+value.f2);}// 获取结果——在不同节点的结果进行汇总后实现@Overridepublic Tuple2<String, Double> getResult(Tuple3<String, Integer, Long> accumulator) {return Tuple2.of(accumulator.f0, (double) accumulator.f2 / accumulator.f1);}// 由于flink是分布式,所以在别的节点也会进行累加 ,该方法是不同节点的结果进行汇总// 即累加器之间的累加@Overridepublic Tuple3<String, Integer, Long> merge(Tuple3<String, Integer, Long> a, Tuple3<String, Integer, Long> b) {return Tuple3.of(a.f0,a.f1+b.f1,a.f2+b.f2);}}).print();//4. sink-数据输出//5. execute-执行env.execute();}
}
会话窗口
package com.bigdata.day04;public class _03_会话窗口 {public static void main(String[] args) throws Exception{StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();env.setRuntimeMode(RuntimeExecutionMode.AUTOMATIC);env.setParallelism(1);DataStreamSource<String> source = env.socketTextStream("localhost", 8889);source.map(new MapFunction<String, Tuple2<String,Integer>>() {@Overridepublic Tuple2<String, Integer> map(String value) throws Exception {String[] s = value.split(" ");return Tuple2.of(s[0],Integer.valueOf(s[1]));}}).keyBy(new KeySelector<Tuple2<String, Integer>, String>() {@Overridepublic String getKey(Tuple2<String, Integer> value) throws Exception {return value.f0;}// 1、主要就是 ProcessingTimeSessionWindows 参数的使用// 2、使用 EventTimeSessionWindows的时候,若没有水印就不会有结果}).window(ProcessingTimeSessionWindows.withGap(Time.seconds(5))).reduce(new ReduceFunction<Tuple2<String, Integer>>() {@Overridepublic Tuple2<String, Integer> reduce(Tuple2<String, Integer> value1, Tuple2<String, Integer> value2) throws Exception {return Tuple2.of(value1.f0,value1.f1+value2.f1);}}).print();env.execute();}
}
相关文章:

flink学习(7)——window
概述 窗口的长度(大小): 决定了要计算最近多长时间的数据 窗口的间隔: 决定了每隔多久计算一次 举例:每隔10min,计算最近24h的热搜词,24小时是长度,每隔10分钟是间隔。 窗口的分类 1、根据window前是否调用keyBy分为键控窗口和非键控窗口…...
restTemplate get请求
报错解释: 这个报错信息表明在使用RestTemplate进行GET请求时,需要提供一个请求类型(reqType),但是传入的值为空。这通常意味着在构建请求或者调用方法时,没有正确设置请求的Content-Type头部,…...
ffmpeg 预设的值 加速
centos 安装ffmpeg 编译安装 官网获取最新的linux ffmpeg 代码 https://ffmpeg.org//releases/ mkdir -p /data/app/ffmpeg cd /data/app/ffmpeg wget http://www.ffmpeg.org/releases/ffmpeg-7.1.tar.gz tar -zxvf ffmpeg-7.1.tar.gz#安装所需的编译环境 yum install -y \…...
maven <scope>compile</scope>作用
在 Maven 项目中, 元素用于定义依赖项的作用范围。 元素可以有多个值,每个值表示不同的作用范围。其中,scope compile scope 是默认的作用范围,表示该依赖项在编译、测试和运行时都需要。 scope compile scope 的含义 1、编译时…...

Ubuntu Server 22.04.5 从零到一:详尽安装部署指南
文章目录 Ubuntu Server 22.04.5 从零到一:详尽安装部署指南一、部署环境二、安装系统2.1 安装2.1.1 选择安装方式2.1.2 选择语言2.1.3 选择不更新2.1.4 选择键盘标准2.1.5 选择安装版本2.1.6 设置网卡2.1.7 配置代理2.1.8 设置镜像源2.1.9 选择装系统的硬盘2.1.10 …...
反射机制了解
反射概念 了解反射背景 存在某些变量或形参的声明类型是Object类型,但是程序却需要调用该对象运行时类型的方法,该方法不是Object中的方法,如何解决。转到如何获取该对象运行时类型的方法。 只能运行时才能获取,这就用到反射。 …...
机器学习策略Ⅰ
机器学习策略Ⅰ 在构建一个好的监督学习系统时,通常需要确保以下四个方面: 系统需要在训练集上能够很好地拟合数据,达到某种可接受的性能水平(如接近人类水平)。如果训练集表现不好,可以使用更大的模型&…...
redis中的bigkey及读取优化
一、bigKey介绍 1、简介 在 Redis 中,Big Key(大键)指的是占用大量内存的单个键。通常,Redis 是一个高性能的内存数据库,但是当某些键变得非常大时,会带来性能上的影响。例如,大量的内存消耗、长时间的操作延迟,甚至可能导致 Redis 停止响应或崩溃。 通俗的来说,指…...

【西瓜书】支持向量机(SVM)
支持向量机(Support Vector Machine,简称SVM)。 超平面 分类学习最基本的想法就是基于训练集合D在样本空间中找到一个划分超平面,将不同类别的样本分开。 但能将训练样本分开的划分超平面可能有很多,应该努力去找到哪…...

三维渲染中顺序无关的半透明混合(OIT)(二——Stencil Route)
1、A-Buffer算法。 在谈到Stencil Route之前,需要先讨论A-Buffer算法。A-Buffer是一种图形学(渲染方向)上的用于可见面分析(Visble Surface Detection)的技术,是Z-Buffer的衍生方法。 Z-Buffer是用于剔除 不透明 物体的算法。假…...
(SAST检测规则-3)固定的 SessionID 缺陷详解
漏洞类型: 会话固定攻击(Session Fixation Attack) 漏洞描述: 会话固定攻击是利用服务器的会话管理机制存在漏洞,攻击者通过提前控制或预测用户的会话标识符(Session ID),当用户登录…...
【安卓开发】【Android Studio】项目构建(Build)时报错:Integer Overflow
一、问题描述 在安卓项目中,构建(Build)失败并报错:xxxxx Integer Overflow(整型溢出)。 二、相关代码 刚开始以为是某个整数(例如控件、java类)不匹配造成的,检查如下…...
STM32主要功能
STM32 是由意法半导体(STMicroelectronics)推出的一系列基于 ARM Cortex-M 内核的微控制器(MCU)。STM32 微控制器广泛应用于嵌入式系统中,因其高性能、低功耗、丰富的外设接口和多种封装形式而被广泛采用。其主要功能和…...

MacOS 如何连接 Linux NFS 服务器
以 Ubuntu 为例。 Ubuntu 服务器端设置 1. 进入 root 权限,安装 NFS 服务: apt-get update apt-get install nfs-kernel-server2. 创建共享目录: mkdir /data chown nobody:nogroup /data chmod 777 /data3. 配置 /etc/exports 文件: vi …...

【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-39
文件下载与邀请翻译者 学习英特尔开发手册,最好手里这个手册文件。原版是PDF文件。点击下方链接了解下载方法。 讲解下载英特尔开发手册的文章 翻译英特尔开发手册,会是一件耗时费力的工作。如果有愿意和我一起来做这件事的,那么ÿ…...

摄影相关常用名词
本文介绍与摄影相关的常用名词。 曝光 Exposure 感光元件接收光线的过程,决定图像的明暗程度和细节表现。 光圈 Aperture 控制镜头进光量的孔径大小,用 F 值(f-stop) 表示。 光圈越大(F 值越小),…...
02.06、回文链表
02.06、[简单] 回文链表 1、题目描述 编写一个函数,检查输入的链表是否是回文的。 2、解题思路: 快慢指针找中点: 利用快慢指针的技巧来找到链表的中间节点。慢指针 slow 每次移动一步,而快指针 fast 每次移动两步。这样&…...

Shell脚本小练习
学习了这么长时间Shell脚本,总得来一次小小的练习吧,那么请看下文! 1.用Shell写一个小计算器。 通过read命令获取用户输入的表达式,表达式的格式设定为操作数1 运算符 操作数2,例如53,然后利用设计的脚本…...

四轮转向轮式里程计设计(python)
目录 写在前面的话参考教程官方教程参考代码(c) 关键代码解析订阅车轮速度订阅车轮转向订阅四轮转向控制模式积累速度和转向角发布里程计 完整代码完整视频演示 写在前面的话 上一篇博客:键盘控制车子四轮转向 这篇文章通过订阅车轮的速度和…...

多方法做配对样本t检验(三)
Wilcoxon符号秩检验 Wilcoxon符号秩检验(Wilcoxon Signed-Rank Test) 是一种非参数统计方法,用于检验两组相关样本(配对样本)之间的差异是否显著。它通常用来代替配对样本t检验,特别是在数据不符合正态分布…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...