Flink学习(十五) 滑动事件时间窗口加上水位线开始窗口时间如何确定?(底层源码)
先看上一节的代码程序
package com.wyh.windowsApi import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import org.apache.flink.streaming.api.functions.{AssignerWithPeriodicWatermarks, AssignerWithPunctuatedWatermarks}
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.watermark.Watermark
import org.apache.flink.streaming.api.windowing.assigners.SlidingEventTimeWindows
import org.apache.flink.streaming.api.windowing.time.Time object WindowTest {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment env.setParallelism(1)
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
//周期性生成watermark 默认是200毫秒
env.getConfig.setAutoWatermarkInterval(100L) /**
* 从文件中读取数据
*
*
*/
//val stream = env.readTextFile("F:\\flink-study\\wyhFlinkSD\\data\\sensor.txt") val stream = env.socketTextStream("localhost", 7777) //Transform操作
val dataStream: DataStream[SensorReading] = stream.map(data => {
val dataArray = data.split(",")
SensorReading(dataArray(0).trim, dataArray(1).trim.toLong, dataArray(2).trim.toDouble)
})
//===到来的数据是升序的,准时发车,用assignAscendingTimestamps
//指定哪个字段是时间戳 需要的是毫秒 * 1000
// .assignAscendingTimestamps(_.timestamp * 1000)
//===处理乱序数据
// .assignTimestampsAndWatermarks(new MyAssignerPeriodic())
//==底层也是周期性生成的一个方法 处理乱序数据 延迟1秒种生成水位 同时分配水位和时间戳 括号里传的是等待延迟的时间
.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[SensorReading](Time.seconds(1)) {
override def extractTimestamp(t: SensorReading): Long = {
t.timestamp * 1000
}
}) //统计10秒内的最小温度
val minTemPerWindowStream = dataStream
.map(data => (data.id, data.temperature))
.keyBy(0)
// .timeWindow(Time.seconds(10)) //开时间窗口 滚动窗口 没有数据的窗口不会触发
//左闭右开 包含开始 不包含结束 延迟1秒触发的那个时间的数据不包含
//可以直接调用底层方法,第三个参数传offset代表时区
//.window(SlidingEventTimeWindows.of(Time.seconds(15),Time.seconds(5),Time.hours(-8)))
.timeWindow(Time.seconds(15), Time.seconds(5)) //滑动窗口,每隔5秒输出一次
.reduce((data1, data2) => (data1._1, data1._2.min(data2._2))) //用reduce做增量聚合 minTemPerWindowStream.print("min temp") dataStream.print("input data") env.execute("window Test") } } //设置水位线(水印) 这里有两种方式实现
//一种是周期性生成 一种是以数据的某种特性进行生成水位线(水印)
/**
* 周期性生成watermark 默认200毫秒
*/
class MyAssignerPeriodic() extends AssignerWithPeriodicWatermarks[SensorReading] {
val bound: Long = 60 * 1000
var maxTs: Long = Long.MaxValue override def getCurrentWatermark: Watermark = {
//定义一个规则进行生成
new Watermark(maxTs - bound)
} //用什么抽取这个时间戳
override def extractTimestamp(t: SensorReading, l: Long): Long = {
//保存当前最大的时间戳
maxTs = maxTs.max(t.timestamp)
t.timestamp * 1000
}
} /**
* 乱序生成watermark
* 每来一条数据就生成一个watermark
*/
class MyAssignerPunctuated() extends AssignerWithPunctuatedWatermarks[SensorReading] {
override def checkAndGetNextWatermark(t: SensorReading, l: Long): Watermark = {
new Watermark(l)
} override def extractTimestamp(t: SensorReading, l: Long): Long = {
t.timestamp * 1000
}
}
开始点源码 Ctrl + 鼠标左键

点进去发现是KededStream里面的其中一个方法,继续点

我们发现实际上是封装了一层java代码,代码中TimeWindow本身就是一个简写,这里发现底层还是.window() 方法 传入窗口类型参数

我们发现,如果窗口的时间是处理时间就调用滑动处理时间窗口,我们在代码中设置了事件时间,
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
所以这里是滑动事件处理时间窗口。
继续点

点进去我们就看到实现的方法了

先来看最开始的时间是如何生成的,继续点

我们就看到这样的一个计算公式

来解释一下,我们可以看到这样一个参数,offset,它如果我们没有设置就默认为0。它本身是用来指定时间的时区的。注意:这里有个参数其实叫windowSize 其实传进来的是一个滑动步长!!!但是不影响结果
如何在代码中添加这个offset呢:.window() 方法中传入
SlidingEventTimeWindows.of() 第三个参数就是offset
.window(SlidingEventTimeWindows.of(Time.seconds(15),Time.seconds(5),Time.hours(-8)))
在这里,就计算出第一个窗口开始时间。
继续看调用的

我们可以看到,一个for循环追加了好多窗口window.
判断如果开始时间大于时间戳减去窗口的大小,那么就把当前这个窗口加上一个创建口大小,然后再减去一个滑动步长,再判断是否大于时间戳减去窗口的大小,以此类推,知道小于,就结束创建,就可以得出最早创建的窗口。

如果是滚动窗口,传进来的就是最早结束的时间,直接加上窗口大小

Flink学习(十五) 滑动事件时间窗口加上水位线开始窗口时间如何确定?(底层源码)的更多相关文章
- 第三百三十五节,web爬虫讲解2—Scrapy框架爬虫—豆瓣登录与利用打码接口实现自动识别验证码
第三百三十五节,web爬虫讲解2—Scrapy框架爬虫—豆瓣登录与利用打码接口实现自动识别验证码 打码接口文件 # -*- coding: cp936 -*- import sys import os ...
- 【OpenCV新手教程之十五】水漫金山:OpenCV漫水填充算法(Floodfill)
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/28261997 作者:毛星云( ...
- Android开发之漫漫长途 Ⅵ——图解Android事件分发机制(深入底层源码)
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...
- 强化学习(十五) A3C
在强化学习(十四) Actor-Critic中,我们讨论了Actor-Critic的算法流程,但是由于普通的Actor-Critic算法难以收敛,需要一些其他的优化.而Asynchronous Adv ...
- NLP(十五)让模型来告诉你文本中的时间
背景介绍 在文章NLP入门(十一)从文本中提取时间 中,笔者演示了如何利用分词.词性标注的方法从文本中获取时间.当时的想法比较简单快捷,只是利用了词性标注这个功能而已,因此,在某些地方,时间的识别 ...
- android开发学习之ViewPager滑动事件讲解
android ViewPager滑动事件讲解 今天在做项目的时候,由于要处理viewPager页面滑动的事件,所以对其进行了一个小小的研究: 首先ViewPager在处理滑动事件的时候要用到OnPa ...
- Vue学习笔记五:事件修饰符
目录 什么是事件修饰符 没有事件修饰符的问题 HTML 运行 使用事件修饰符 .stop阻止冒泡 .prevent 阻止默认事件 .capture 添加事件侦听器时使用事件捕获模式 .self 只当事 ...
- python学习(十五) 内建模块学习
介绍python的几个內建模块,原文链接 1 python的时间模块datetime 取现在时间 from datetime import datetime now = datetime.now() ...
- Scala学习十五——注解
一.本章要点 可以为类.方法.字段.局部变量.参数.表达式.类型参数以及各种类型定义添加注解 对于表达式和类型,注解跟在被注解的条目之后 注解的形式有@Annotation.@Annotation(v ...
- JAVA多线程学习十五 - 阻塞队列应用
一.类相关属性 接口BlockingQueue<E>定义: public interface BlockingQueue<E> extends Queue<E> { ...
随机推荐
- ES6 面试题
新增了哪些属性? 新增块级作用域:let.const 新增数据类型:Symbol 表示独一无二的值 新增数据结构: Set,类似数组,所有数据是唯一的: Map,键值对的结合,传统的 Object 只 ...
- OpenType 字体文件组织结构
OpenType 字体文件结构 OpenType 字体的组织 https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organi ...
- 金Gien乐道 | 10月热点回顾
收获之秋,中电金信Q4开篇捷报不断 Q4开篇,中电金信迎来多个捷报.公司与青岛财通集团联合打造的核心业务系统(一体化业务平台)一期项目顺利投产上线并平稳运行:中标华南某全国性股份制商业银行新一 ...
- 拦截烂SQL,解读GaussDB(DWS)查询过滤器过滤规则原理
本文分享自华为云社区<GaussDB(DWS)查询过滤器过滤规则原理与使用介绍>,作者: 清道夫. 1. 前言 适用版本:[9.1.0.100(及以上)] 查询过滤器在9.1.0.100之 ...
- Ubuntu sudo nopasswd方法
1 运行 visudo 2 假设用户名为yourname, 则在最后一行添加: # User privilege specificationroot ALL=(ALL:ALL) ALL# Member ...
- arch 输入法
输入法配置 输入法采用fcitx + Sogou的组合,安装需要的包: yay -S fcitx fcitx-im fcitx-configtool fcitx-sogoupinyin 然后写一个fc ...
- 用 Cursor 写出第一个程序
大家好,我是汤师爷 最近几个月,Cursor迅速走红,成为一款强大的编程助手.Cursor不仅使用简单,而且通过集成各种大模型技术,编程能力一流. Cursor是什么? Cursor是一个类似VSCo ...
- Qt编写物联网管理平台49-设备模拟工具
一.前言 本系统专门配备了设备模拟工具,用来在没有外接真实设备的时候,模拟modbus协议数据,支持多个设备,支持串口和网络方式,可切换正常数据和报警数据,反应到主程序上.对应主程序中两种端口,一种是 ...
- [转]Vetur can't find `tsconfig.json` or `jsconfig.json` in d:\VueProjects\myroute.
vue界面启动项目 visual code报错 如下图,找到 Ignore Project Warning 前边打上对勾
- 命名空间“System.Web.UI.Design”中不存在类型或命名空间名称“ControlDesigner”
命名空间"System.Web.UI.Design"中不存在类型或命名空间名称"ControlDesigner" 命名空间"System.Web.UI ...