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

0基础学习PyFlink——事件时间和运行时间的窗口

大纲

  • 定制策略
  • 运行策略
  • Reduce
  • 完整代码
  • 滑动窗口案例
  • 参考资料

在 《0基础学习PyFlink——时间滚动窗口(Tumbling Time Windows)》一文中,我们使用的是运行时间(Tumbling ProcessingTimeWindows)作为窗口的参考时间:

    reduced=keyed.window(TumblingProcessingTimeWindows.of(Time.milliseconds(2))) \.apply(SumWindowFunction(),Types.TUPLE([Types.STRING(), Types.INT()]))

而得到的结果也是不稳定的。
在这里插入图片描述
这是因为每次运行时,CPU等系统资源的繁忙程度是不一样的,这就影响了最后的运行结果。
为了让结果稳定,我们可以不依赖运行时间(ProcessingTime),而使用不依赖于运行环境,只依赖于数据的事件时间(EventTime)。
一般,我们需要大数据处理的数据,往往存在一个字段用于标志该条数据的“顺序”。这个信息可以是单调递增的ID,也可以是不唯一的时间戳。我们可以将这类信息看做事件发生的时间。
那如何让输入的数据中的“事件时间”参与到窗口时长的计算中呢?这儿就要引入时间戳和Watermark(水位线)的概念。
假如我们把数据看成一张纸上的内容,水位线则是这张纸的背景。它并不影响纸上内容的表达,只是系统要用它来做更多的事情。
将数据中表达“顺序”的数据转换成时间戳,我们可以使用水位线单调递增时间戳分配器

定制策略

class ElementTimestampAssigner(TimestampAssigner):def extract_timestamp(self, value, record_timestamp)-> int:return int(value[1])……       # define the watermark strategywatermark_strategy = WatermarkStrategy.for_monotonous_timestamps() \.with_timestamp_assigner(ElementTimestampAssigner())

for_monotonous_timestamps会分配一个水位线单调递增时间戳分配器,然后使用with_timestamp_assigner告知输入数据中“顺序”字段的值。这样系统就会根据这个字段的值生成一个单调递增的时间戳。这个时间戳相对顺序就和输入数据一样,是稳定的。
比如上图中,会分别用2,1,4,3……来计算时间戳。

运行策略

然后对原始数据使用该策略,这样source_with_wartermarks中的数据就包含了时间戳。

source_with_wartermarks=source.assign_timestamps_and_watermarks(watermark_strategy)

Reduce

这次我们使用TumblingEventTimeWindows,即事件时间(EventTime)窗口,而不是运行时间(ProcessingTime)窗口。

     # keyingkeyed=source_with_wartermarks.key_by(lambda i: i[0]) # reducingreduced=keyed.window(TumblingEventTimeWindows.of(Time.milliseconds(2))) \.apply(SumWindowFunction(),Types.TUPLE([Types.STRING(), Types.INT()]))

(‘E’, 1) TimeWindow(start=0, end=2)
(‘E’, 3) (‘E’, 2) TimeWindow(start=2, end=4)
(‘E’, 4) (‘E’, 5) TimeWindow(start=4, end=6)
(‘E’, 6) (‘E’, 7) TimeWindow(start=6, end=8)
(‘E’, 8) (‘E’, 9) TimeWindow(start=8, end=10)
(‘E’, 10) TimeWindow(start=10, end=12)
(E,1)
(E,2)
(E,2)
(E,2)
(E,2)
(E,1)

多运行几次,结果是稳定输出的。
我们再多关注下TimeWindow中的start和end,它们是不重叠的、步长为2、左闭右开的区间。这个符合滚动窗口特性。

完整代码

from typing import Iterablefrom pyflink.common import Types, Time, WatermarkStrategy
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode, WindowFunction
from pyflink.datastream.window import TumblingEventTimeWindows, TimeWindow, TumblingProcessingTimeWindows, SlidingProcessingTimeWindows
from pyflink.common.watermark_strategy import TimestampAssignerclass ElementTimestampAssigner(TimestampAssigner):def extract_timestamp(self, value, record_timestamp)-> int:return int(value[1])class SumWindowFunction(WindowFunction[tuple, tuple, str, TimeWindow]):def apply(self, key: str, window: TimeWindow, inputs: Iterable[tuple]):print(*inputs, window)return [(key,  len([e for e in inputs]))]word_count_data = [("E",3),("E",1),("E",4),("E",2),("E",6),("E",5),("E",7),("E",8),("E",9),("E",10)]def word_count():env = StreamExecutionEnvironment.get_execution_environment()env.set_runtime_mode(RuntimeExecutionMode.STREAMING)# write all the data to one fileenv.set_parallelism(1)source_type_info = Types.TUPLE([Types.STRING(), Types.INT()])# define the source# mappgingsource = env.from_collection(word_count_data, source_type_info)# source.print()# define the watermark strategywatermark_strategy = WatermarkStrategy.for_monotonous_timestamps() \.with_timestamp_assigner(ElementTimestampAssigner())source_with_wartermarks=source.assign_timestamps_and_watermarks(watermark_strategy)# keyingkeyed=source_with_wartermarks.key_by(lambda i: i[0]) # reducingreduced=keyed.window(TumblingEventTimeWindows.of(Time.milliseconds(2))) \.apply(SumWindowFunction(),Types.TUPLE([Types.STRING(), Types.INT()]))# # define the sinkreduced.print()# submit for executionenv.execute()if __name__ == '__main__':word_count()

滑动窗口案例

from typing import Iterablefrom pyflink.common import Types, Time, WatermarkStrategy
from pyflink.datastream import StreamExecutionEnvironment, RuntimeExecutionMode, WindowFunction
from pyflink.datastream.window import SlidingEventTimeWindows, TimeWindow
from pyflink.common.watermark_strategy import TimestampAssignerclass ElementTimestampAssigner(TimestampAssigner):def extract_timestamp(self, value, record_timestamp)-> int:return int(value[1])class SumWindowFunction(WindowFunction[tuple, tuple, str, TimeWindow]):def apply(self, key: str, window: TimeWindow, inputs: Iterable[tuple]):print(*inputs, window)return [(key,  len([e for e in inputs]))]word_count_data = [("E",3),("E",1),("E",4),("E",2),("E",6),("E",5),("E",7),("E",8),("E",9),("E",10)]def word_count():env = StreamExecutionEnvironment.get_execution_environment()env.set_runtime_mode(RuntimeExecutionMode.STREAMING)# write all the data to one fileenv.set_parallelism(1)source_type_info = Types.TUPLE([Types.STRING(), Types.INT()])# define the source# mappgingsource = env.from_collection(word_count_data, source_type_info)# source.print()# define the watermark strategywatermark_strategy = WatermarkStrategy.for_monotonous_timestamps() \.with_timestamp_assigner(ElementTimestampAssigner())source_with_wartermarks=source.assign_timestamps_and_watermarks(watermark_strategy)# keyingkeyed=source_with_wartermarks.key_by(lambda i: i[0]) # reducingreduced=keyed.window(SlidingEventTimeWindows.of(Time.milliseconds(2), Time.milliseconds(1))) \.apply(SumWindowFunction(),Types.TUPLE([Types.STRING(), Types.INT()]))# # define the sinkreduced.print()# submit for executionenv.execute()if __name__ == '__main__':word_count()

(‘E’, 1) TimeWindow(start=0, end=2)
(‘E’, 1) (‘E’, 2) TimeWindow(start=1, end=3)
(‘E’, 3) (‘E’, 2) TimeWindow(start=2, end=4)
(‘E’, 3) (‘E’, 4) TimeWindow(start=3, end=5)
(‘E’, 4) (‘E’, 5) TimeWindow(start=4, end=6)
(‘E’, 6) (‘E’, 5) TimeWindow(start=5, end=7)
(‘E’, 6) (‘E’, 7) TimeWindow(start=6, end=8)
(‘E’, 7) (‘E’, 8) TimeWindow(start=7, end=9)
(‘E’, 8) (‘E’, 9) TimeWindow(start=8, end=10)
(‘E’, 9) (‘E’, 10) TimeWindow(start=9, end=11)
(‘E’, 10) TimeWindow(start=10, end=12)
(E,1)
(E,2)
(E,2)
(E,2)
(E,2)
(E,2)
(E,2)
(E,2)
(E,2)
(E,2)
(E,1)

通过TimeWindow的信息,我们看到这是一个步长为1、长度为2左闭右开的窗口。这个符合滑动窗口特点。

在这里插入图片描述

参考资料

  • https://nightlies.apache.org/flink/flink-docs-release-1.18/zh/docs/dev/datastream/event-time/built_in/
  • https://nightlies.apache.org/flink/flink-docs-release-1.18/zh/docs/learn-flink/streaming_analytics/

相关文章:

0基础学习PyFlink——事件时间和运行时间的窗口

大纲 定制策略运行策略Reduce完整代码滑动窗口案例参考资料 在 《0基础学习PyFlink——时间滚动窗口(Tumbling Time Windows)》一文中,我们使用的是运行时间(Tumbling ProcessingTimeWindows)作为窗口的参考时间: reducedkeyed.window(TumblingProcess…...

Git Rebase 优化项目历史

在软件开发过程中,版本控制是必不可少的一环。Git作为当前最流行的版本控制系统,为开发者提供了强大的工具来管理和维护代码历史。git rebase是其中一个高级特性,它可以用来重新整理提交历史,使之更加清晰和线性。本文将详细介绍g…...

两种MySQL OCP认证应该如何选?

很多同学都找姚远老师说要参加MySQL OCP认证培训,但绝大部分同学并不知道MySQL OCP认证有两种,以MySQL 8.0为例。 一种是管理方向,叫:Oracle Certified Professional, MySQL 8.0 Database Administrator(我考试的比较…...

Java用log4j写日志

日志可以方便追踪和调试问题,以前用log4net写日志,换Java了改用log4j写日志,用法和log4net差不多。 到apache包下载下载log4j的包,解压后把下图两个jar包引入工程 先到网站根下加一个log4j2.xml的配置文件来配置日志的格式和参…...

PCTA认证考试-01_TiDB数据库架构概述

TiDB 数据库架构概述 一、学习目标 理解 TiDB 数据库整体结构。了解 TiDB Server,TiKV,TiFlash 和 PD 的主要功能。 二、TiDB 体系架构 1. TiDB Server 2. TiKV OLTP 3. Placement Driver 4. TiFlash OLAP OLTPOLAPHTAP...

路由过滤路由引入

目录 一、实验拓扑 二、实验需求 三、实验步骤 1、配置IP地址 2、配置RIP和OSPF 3、配置路由引入 4、使用路由过滤,使 R4 无法学到 R1 的业务网段路由,要求使用 prefix-list 进行匹配 5、OSPF 区域中不能出现 RIP 协议报文 一、实验拓扑 二、实…...

视频剪辑技巧:批量合并视频,高效省时,添加背景音乐提升品质

随着社交媒体的兴起,视频制作越来越受到人们的关注。掌握一些视频剪辑技巧,可以让我们轻松地制作出令人惊艳的视频。本文将介绍一种高效、省时的视频剪辑技巧,帮助您批量合并视频、添加背景音乐,并提升视频品质。现在一起来看看云…...

数据可视化篇——pyecharts模块

在之前的文章中我们已经介绍过爬虫采集到的数据用途之一就是用作可视化报表,而pyecharts作为Python中可视化工具的一大神器必然就受到广大程序员的喜爱。 一、什么是Echarts? ECharts 官方网站 : https://echarts.apache.org/zh/index.html ECharts 是…...

Python--快速入门二

Python--快速入门二 1.Python数据类型 1.可以通过索引获取字符串中特定位置的字符: a "Hello" print(a[3]) 2.len函数获取字符串的长度: a "Hello" print(a) print(len(a)) 3.空值类型表示完全没有值: 若不确定当…...

【ArcGIS Pro二次开发】(74):Python、C#实现Excel截图导出图片

以村庄规划制图为例,通过对现状和规划用地的统计,生成Excel格式的【空间功能结构调整表】后,需要进一步将表格导出成图片,并嵌入到图集中,这样可以实现全流程不用手动参与,让制图的流程完全自动化。 关于E…...

74HC138逻辑芯片

文章目录 74系列逻辑芯片——74HC138基础信息描述特征应用范围 功能信息封装引脚基本电路 扩展性能分析 74系列逻辑芯片——74HC138 基础信息 描述 74HC138器件设计用于需要极短传播延迟时间的高性能存储器解码或数据路由应用;在高性能存储系统中,可使用…...

【架构图解】API架构图解:如何以图表形式展现复杂系统

文章目录 前言序列图组件图数据流程图结论 前言 架构图是链接到 API 的不同组件/服务如何相互交互的直观表示。 当需要理解 API 的架构并将其传达给不同的利益相关者(包括其他开发人员、项目经理和客户)时,这些图表非常有用。 图表/视觉效…...

D-link未授权访问以及远程代码执行

随便输入一个错误密码,会跳转到页面: /page/login/login.html?errorfail继续访问有效页面漏洞url: /Admin.shtml然后访问管理页面去更改管理密码 直接构造payload访问漏洞url: /cgi-bin/execute_cmd.cgi?cmdid执行命令&#…...

flask踩坑集锦

很久之前用过flask,那时候是跟着教程,教程怎么做我就怎么做,没有仔细考虑过。 现在是全靠文档和搜索一步一步搭建,忘了很多东西,就碰了很多壁,浅浅记录一下子。 1.Jinja2的模板继承,是指抽出每…...

VulnHub jarbas

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏…...

基因预测软件prodigal的使用

Prodigal是一款常用的基因预测软件,可以用于预测原核生物基因组中的开放阅读框(ORF),并根据不同的编码调用方式(如起始密码子和终止密码子)对其进行注释。 以下是使用Prodigal进行基因预测的步骤&#xff…...

银行存取款系统

题目 ​ 一个简单的存取款系统,用户可以选择存钱、取钱、转账、修改密码和退出系统等业务。程序使用了菜单界面来展示业务选项,并根据用户的选择调用相应的函数进行处理。具体功能如下: 登录:实现登录功能,需要输入正确密码才能进入菜单系统。 菜单:显示菜单界面,列出其…...

ConnectionError: HTTPSConnectionPool

ConnectionError: HTTPSConnectionPool(host‘zbbfxstatic.figtingdream.com’, port443): Max retries exceeded with url: /api/cache (Caused by NewConnectionError(‘<urllib3.connection.HTTPSConnection object at 0x00000249795AD9A0>: Failed to establish a ne…...

YOLO系列环境配置及训练

目录 前言 一、下载所需 1、Anaconda安装 2、NVIDIA 驱动程序安装 3、CUDA安装 4、CUDNN下载及配置 二、环境配置 1、虚拟环境创建 2、Pytorch安装 3、pycharm环境切换及剩余库的安装 4、YOLO代码的测试及训练配置步骤 &#xff08;1&#xff09;测试 &#xff08…...

推荐PHP付费进群源码

PHP付费进群源码带自动定位基于ThinkPHP框架开发的&#xff0c;可以快速搭建知识付费粉丝进群。 更新&#xff1a; 1.首页付款轮播 2.城市定位功能 3.更新及优化域名库及支付设置 4.新增一张图模板设置模式&#xff0c;简化后台模板设置 5.前后台其他优化 演示地址&#xff1a…...

Maven修改仓库和镜像地址

目录 1、修改仓库地址2、修改镜像地址 1、修改仓库地址 使用IDEA时,如果不指定自己下载的Maven,idea会默认使用自带的Maven 3&#xff08;bundle)。maven 3默认的仓库路径一般是在c盘的用户文件夹中的.m2目录下&#xff1a; 当maven下的pom文件中的依赖逐渐增加时,maven仓库下…...

【m98】接收udp包到变为CopyOnWriteBuffer的rtp包及call模块传递的过程

RtpTransport::OnReadPacket ice和Dtls 传输的创建及1个简单的SFU转发实例 实例生动的再现了这一过程: 【webrtc】接收/发送的rtp包、编解码的VCM包、CopyOnWriteBuffer 对于m98的代码,进行走读,大体了解到类似的过程: \src\pc\rtp_transport.cc 收到的data指针和长度len 直…...

synchronized 到底锁的是谁?

synchronized 到底锁的是谁&#xff1f; 修饰方法&#xff1a; 1、静态方法 2、非静态方法&#xff0c;锁住的是方法的调用者 修饰代码块 1、synchronized修饰非静态方法 锁住的是方法的调用者 锁住实例 流程&#xff1a; 1、线程A先拿到synModel对象然后给这个 synModel对象…...

第六章:进制转换与数据存储

系列文章目录 文章目录 系列文章目录前言一、进制二、进制的转换三、原码、反码、补码总结 前言 进制转换是程序员的基本功。 一、进制 进制组成二进制0-1 &#xff0c;满2进1以0b或0B开头十进制0-9 &#xff0c;满10进1八进制0-7&#xff0c;满8进1以数字0开头表示十六进制0…...

【微服务】mysql + elasticsearch数据双写设计与实现

目录 一、前言 二、为什么使用mysqles双写 2.1 单用mysql的问题 2.2 为什么不直接使用es 2.2.1 非关系型表达 2.2.2 不支持事务 2.2.3 多字段将造成性能低下 三、mysqles双写方案设计要点 3.1 全新设计 VS 中途调整架构 3.2 全表映射 VS 关键字段存储 3.2.1 最大程度…...

《向量数据库指南》——用了解向量数据库Milvus Cloud搭建高效推荐系统

了解向量数据库 ANN 搜索是关系型数据库无法提供的功能。关系型数据库只能用于处理具有预定义结构、可直接比较值的表格型数据。因此,关系数据库索引也是基于这一点来比较数据。但是 Embedding 向量无法通过这种方式直接相互比较。因为我们不知道向量中的每个值代表什么意思,…...

EtherCAT主站SOEM -- 4 -- SOEM之ethercatprint.h/c文件解析

EtherCAT主站SOEM -- 4 -- SOEM之ethercatprint.h/c文件解析 一 ethercatprint.h/c文件功能预览&#xff1a;二 ethercatprint.h/c 文件的主要函数的作用&#xff1a;2.1.1 char* ec_sdoerror2string(uint32 sdoerrorcode)2.1.2 char* ec_ALstatuscode2string(uint16 ALstatusc…...

Redis01-缓存击穿、穿透和雪崩

目录 开场白-追命3连 使用场景 01缓存穿透场景与方案 02布隆过滤器 03缓存击穿场景与方案 04缓存雪崩场景与方案 开场白-追命3连 看你项目中有说用到Redis&#xff0c;都是哪些场景使用了Redis呢&#xff1f; 如果发生了缓存穿透、击穿、雪崩如何应对呢&#xff1f;缓存…...

multiple kernel learning(MKL)多核学习

历史上之所以会出现多核学习&#xff08;MKL&#xff09;这个词&#xff0c;是因为在深度学习流行起来以前&#xff0c;kernel是处理非线性的默认方法&#xff0c;那个年代优化一个非线性函数不容易&#xff0c;每加一层复杂性可能就需要多设计一个优化算法&#xff0c;MKL就是…...

JS匿名函数之函数表达式与立即执行函数

匿名函数是什么&#xff1f;和具名函数有什么区别&#xff1f;让我为大家介绍一下吧&#xff01; 没有名字的函数&#xff0c;无法直接使用 一.函数表达式 将匿名函数赋值给一个变量&#xff0c;并且通过变量名去调用&#xff0c;我们将这个称为函数表达式 语法&#xff1a; …...