一、Time

在Flink的流式处理中,会涉及到时间的不同概念

Event Time(事件时间):是事件创建的时间。它通常由事件中的时间戳描述,例如采集的日志数据中,每一条日志都会记录自己的生成时间,Flink通过时间戳分配器访问事件时间戳

Ingestion Time(采集时间):是数据进入Flink的时间

Processing Time(处理时间):是每一个执行基于时间操作的算子的本地系统时间,与机器相关,默认的时间属性就是Processing Time。

例如一条日志进入Flink的时间为2017-11-12 10:00:00.123 到达window的系统时间为 2017-11-12 10:00:01.234,日志内容如下:

2017-11-02 18:37:15.624 INFO Fair over to rm2

对于业务来说,要统计1min内的故障日志个数,哪个时间是最有意义的?----- eventTime,因为我们要根据日志的生成时间进行统计。

如果要想聚合,不可能对无解数据流进行聚合。

二、Window

1、streaming流式计算是一种被设计用于处理处理无限数据集的数据处理引擎,而无限数据集是指一种不断增长的本质上无限的数据集,而window是一种切割无限数据为有限块进行处理的手段。

Window是无限数据流处理的核心,Window将一个无限的stream拆分成有限大小的"buckets"桶,我们可以在这些桶上做计算操作。

共有两类,五种时间窗口。

2、Window类型(两类)

2.1、CountWindow:按照指定的数据条数生成一个window,与时间无关

2.2、TimeWindow:按照时间生成window。(按照Processing Time来划分Window)

对于TimeWindow和CountWindow,可以根据窗口实现原理的不同分成三类:滚动窗口(Tumbling Window)、滑动窗口(Sliding Window)和会话窗口(Session Window)。

(1)滚动窗口(Tumbling Windows)

将数据依据固定的窗口长度对数据进行切分。

特点:时间对齐,窗口长度固定,没有重叠。

滚动窗口分配器将每个元素分配到一个指定窗口大小的窗口中,滚动窗口有一个固定的大小,并且不会出现重叠。

(2)滑动窗口(Sliding Windows)

滑动窗口是固定窗口的更广义的一种形式,滑动窗口由固定的窗口长度和滑动间隔组成。

特点:时间对齐,窗口长度固定,有重叠。

滑动窗口分配器将元素分配到固定长度的窗口中,与滚动窗口类似,窗口的大小由窗口大小参数来配置,另一个窗口滑动参数控制滑动窗口开始的频率。

因此,滑动窗口如果滑动参数小于窗口大小的话,窗口是可以重叠的,在这种情况下元素会被分配到多个窗口中。

使用场景:对最近一个时间段内的统计(求某接口最近5min的失败率来决定是否要报警。)

(3)会话窗口(Session Windows)

由一系列事件组合一个指定时间长度的timeout间隙组成。类似于web应用的session,也就是一段时间没有接收到新数据就会生成新的窗口。

特点:时间无对齐。

session 窗口分配器通过session活动来对元素进行分组,session窗口跟滚动窗口和滑动窗口相比,不会有重叠和固定的开始时间和结束时间的情况,相反,当它在一个固定的

时间周期内不再收到元素,即非活动间隔产生,那这个窗口就会关闭。一个Session窗口通过一个session间隔来配置,这个session间隔定义了非活跃周期的长度,当这个非活跃

周期产生,那么当前的session将关闭并且后续的元素将被分配到新的session窗口中去。

三、Window API

3.1、CountWindow

CountWindow根据窗口中相同key元素的数量来触发执行,执行时只计算元素数量达到窗口大小的key对应的结果。

注意:CountWindow的window_size 指的是相同key的元素的个数,不是输入的所有元素的总数。

import org.apache.flink.api.java.tuple.Tuple
import org.apache.flink.streaming.api.scala.{DataStream, KeyedStream, StreamExecutionEnvironment} /**
* CountWindow 中的滚动窗口(Tumbling Windows)
* 将数据依据固定的窗口长度对数据进行切分。
*/
object TimeAndWindow {
def main(args: Array[String]): Unit = { val env = StreamExecutionEnvironment.getExecutionEnvironment
val stream: DataStream[String] = env.socketTextStream("localhost",11111)
val streamKeyBy: KeyedStream[(String, Long), Tuple] = stream.map(item => (item,1L)).keyBy(0)
//注意:CountWindow的window_size 指的是相同key的元素的个数,不是输入的所有元素的总数。
val streamWindow: DataStream[(String, Long)] = streamKeyBy.countWindow(5)
.reduce((item1, item2)=>(item1._1,item1._2+item2._2)) streamWindow.print()
env.execute("TimeAndWindow") }
}

3.2

import org.apache.flink.api.java.tuple.Tuple
import org.apache.flink.streaming.api.scala.{DataStream, KeyedStream, StreamExecutionEnvironment} /**
* CountWindow 中的滑动窗口(Sliding Windows)
* 将数据依据固定的窗口长度对数据进行切分。
*/
object TimeAndWindow {
def main(args: Array[String]): Unit = { val env = StreamExecutionEnvironment.getExecutionEnvironment
val stream: DataStream[String] = env.socketTextStream("localhost",11111)
val streamKeyBy: KeyedStream[(String, Long), Tuple] = stream.map(item => (item,1L)).keyBy(0)
//注意:CountWindow的window_size 指的是相同key的元素的个数,不是输入的所有元素的总数。
//满足步长,就执行一次,按第一个参数的长度
val streamWindow: DataStream[(String, Long)] = streamKeyBy.countWindow(5,2)
.reduce((item1, item2)=>(item1._1,item1._2+item2._2)) streamWindow.print()
env.execute("TimeAndWindow") }
}

四、EventTime与Window

1、EventTime的引入

在Flink的流式处理中,绝大部分的业务都会使用eventTime,一般只在eventTime无法使用时,才会被迫使用ProcessingTime或者IngestionTime。

如果要使用EventTime,那么需要引入EventTime的时间戳,引入方式如下所示:

2、Watermark

  概念:我们知道,流处理从事件产生,到流经source,再到operator,中间是有一个过程和时间的,虽然大部分情况下,流到operator的数据都是按照事件产生的

事件戳顺序来的,但是也不排除由于网络、背压等原因,导致乱序的产生,所谓乱序,就是指Flink接收到的事件的先后顺序不是严格按照事件的EventTime顺序排列的。

  Watermark是一种衡量Event Time进展的机制,它是数据本身的一个隐藏属性,数据本身携带着对应的Watermark。

  Watermark是用于处理乱序事件的,而正确的处理乱序事件,通常用Watermark机制结合window来实现。

  数据流中的Watermark用于表示eventTime小于Watermark的数量,都已经到达了,因此,window的执行也是由Watermark触发的。

  Watermark可以理解成一个延迟触发机制。我们可以设置Watermark的延时时长t,每次系统会校验已经到达的数据中最大的maxEventTime,然后认定eventTime 小于

maxEventTime-t 的所有数据都已经到达。如果有窗口的停止时间等于maxEventTime-t,那么这个窗口被触发执行。

滚动窗口/滑动窗口/会话窗口


import org.apache.flink.api.java.tuple.Tuple
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.assigners.{EventTimeSessionWindows, SlidingEventTimeWindows, TumblingEventTimeWindows}
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow

/**
* TimeWindow
*/
object EventTimeAndWindow {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
//开启watermark
//从调用时刻开始给env创建的每一个stream追加时间特征。
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)

val stream: KeyedStream[(String, Long), Tuple] = env.socketTextStream("192.168.218.130", 1111).assignTimestampsAndWatermarks(
new BoundedOutOfOrdernessTimestampExtractor[String](Time.milliseconds(3000)) {
override def extractTimestamp(element: String): Long = {
// event word eventTime是日志生成时间,我们从日志中解析EventTime
val eventTime = element.split(" ")(0).toLong
println(eventTime)
eventTime
}
}
).map(item => (item.split(" ")(1),1L)).keyBy(0)
//加上滚动窗口,窗口大小是5s,调用window的api
// val streamWindow: WindowedStream[(String, Long), Tuple, TimeWindow] = stream.window(TumblingEventTimeWindows.of(Time.seconds(5)))
//滑动窗口
// val streamWindow: WindowedStream[(String, Long), Tuple, TimeWindow] = stream.window(SlidingEventTimeWindows.of(Time.seconds(10),Time.seconds(5)))
//会话窗口
val streamWindow: WindowedStream[(String, Long), Tuple, TimeWindow] = stream.window(EventTimeSessionWindows.withGap(Time.seconds(5)))
val streamReduce = streamWindow.reduce((item1,item2)=>(item1._1,item1._2+item2._2))
streamReduce.print()

env.execute("EventTimeAndWindow")
}
}

Flink中的Time与Window的更多相关文章

  1. Flink中API使用详细范例--window

    Flink Window机制范例实录: 什么是Window?有哪些用途? 1.window又可以分为基于时间(Time-based)的window 2.基于数量(Count-based)的window ...

  2. Flink中的window、watermark和ProcessFunction

    一.Flink中的window 1,window简述  window 是一种切割无限数据为有限块进行处理的手段.Window 是无限数据流处理的核心,Window 将一个无限的 stream 拆分成有 ...

  3. Flink 中极其重要的 Time 与 Window 详细解析(深度好文,建议收藏)

    前言 Flink 是流式的.实时的 计算引擎 上面一句话就有两个概念,一个是流式,一个是实时. 流式:就是数据源源不断的流进来,也就是数据没有边界,但是我们计算的时候必须在一个有边界的范围内进行,所以 ...

  4. 《从0到1学习Flink》—— 介绍Flink中的Stream Windows

    前言 目前有许多数据分析的场景从批处理到流处理的演变, 虽然可以将批处理作为流处理的特殊情况来处理,但是分析无穷集的流数据通常需要思维方式的转变并且具有其自己的术语(例如,"windowin ...

  5. Flink中的CEP复杂事件处理 (源码分析)

    其实CEP复杂事件处理,简单来说你可以用通过类似正则表达式的方式去表示你的逻辑,表现能力非常的强,用过的人都知道 开篇先偷一张图,整体了解Flink中的CEP中的  一种重要的图  NFA非确定有限状 ...

  6. 如何在 Apache Flink 中使用 Python API?

    本文根据 Apache Flink 系列直播课程整理而成,由 Apache Flink PMC,阿里巴巴高级技术专家 孙金城 分享.重点为大家介绍 Flink Python API 的现状及未来规划, ...

  7. 老板让阿粉学习 flink 中的 Watermark,现在他出教程了

    1 前言 在时间 Time 那一篇中,介绍了三种时间概念 Event.Ingestin 和 Process, 其中还简单介绍了乱序 Event Time 事件和它的解决方案 Watermark 水位线 ...

  8. 「Flink」Flink中的时间类型

    Flink中的时间类型和窗口是非常重要概念,是学习Flink必须要掌握的两个知识点. Flink中的时间类型 时间类型介绍 Flink流式处理中支持不同类型的时间.分为以下几种: 处理时间 Flink ...

  9. 理解Flink中的Task和SUBTASK

    1.概念 Task(任务):Task是一个阶段多个功能相同的subTask 的集合,类似于Spark中的TaskSet. subTask(子任务):subTask是Flink中任务最小执行单元,是一个 ...

随机推荐

  1. easyui-textbox使用value设置默认值失效

    1,使用easyu-textbox的value参数设置默认值失效,easyui-textbox放到dialog弹框中,当dialog的closed为false时,也就是打开dialog时,设置的val ...

  2. EasyUI学后总结第一集

    1,创建Easyui组件-使用html还是使用js方式? 如果在创建Easyui组件的时候,组件再被更改,那么属于静态组件,对于静态组件不要使用js方式创建--会增加js代码量. 如果创建的Easyu ...

  3. java 向Redis中存放数据 List<Device>转String

    /** * redis服务 */ @Autowired private RedisService redisService; //创建 Device  对象 Device no = new Devic ...

  4. 如何让py生成pyd

    pyd文件类似于C++中的dll,可以编译,但是看不到源代码. py转换成pyd参考链接:https://blog.csdn.net/weixin_44493841/article/details/1 ...

  5. C++第四十五篇 -- MFC关闭调用的窗口

    调用窗体的方法: // chart是一个MFC的窗体类 chart *chartdialog = new chart; //调用窗体,获取返回值 int ReturnValue = chartdial ...

  6. 第十九篇 -- QTableWidget的使用

    QTableWidget的一些常用方法 下面两个类可以根据自己的情况自定义. 单元格类型的类: class CellType(Enum): ctKey = 1000 ctPath = 1001 ctI ...

  7. 构建后端第5篇之---Idea 查看继承 实现关系图

    first question: how to show a class  children class :  move mousrmark to class name , Ctrl + H how t ...

  8. C#曲线分析平台的制作(六,Sqldependency+Signalr+windows 服务)

    在经过五天的学习和资料收集后,终于初步实现了利用sqldependency进行数据库变化监控,signalr进行前后台交互,数据实时更新.下面将源代码贴出进行初步分析: 1.系统整体框架构成: 2.具 ...

  9. mongodb使用场景及与mysql区别

    MySQL是关系型数据库. 优势: 在不同的引擎上有不同 的存储方式. 查询语句是使用传统的sql语句,拥有较为成熟的体系,成熟度很高. 开源数据库的份额在不断增加,mysql的份额页在持续增长. 缺 ...

  10. 3分钟搭建一个网站?腾讯云Serverless开发体验

    作为一个开发者,应该都能理解一个网站从开发到上线,要经过很多繁琐的步骤. 编写代码,部署应用,部署数据库,申请域名,申请SSL证书,域名备案,到最终上线起码要几天时间. 作为一个不精通代码的业务玩家, ...