一、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. Spring解决Attribute tx bound to namespace httpwww.w3.org2000xmlns was already specified

    Spring|解决Attribute "tx" bound to namespace "http://www.w3.org/2000/xmlns/" was a ...

  2. 【spring源码系列】之【Bean的循环依赖】

    希望之光永远向着目标清晰的人敞开. 1. 循环依赖概述 循环依赖通俗讲就是循环引用,指两个或两个以上对象的bean相互引用对方,A依赖于B,B依赖于A,最终形成一个闭环. Spring循环依赖的场景有 ...

  3. 如何进行TIDB优化之Grafana(TiDB 3.0)关注监控指标

    前言 在对数据库进行优化前,我们先要思考一下数据库系统可能存在的瓶颈所在之外.数据库服务是运行在不同的硬件设备上的,优化即通过参数配置(不考虑应用客户端程序的情况下),而实现硬件资源的最大利用化.那么 ...

  4. noip模拟26[肾炎黄·酱累黄·换莫黄]

    \(noip模拟26\;solutions\) 这个题我做的确实是得心应手,为啥呢,因为前两次考试太难了 T1非常的简单,只不过我忘记了一个定理, T2就是一个小小的线段树,虽然吧我曾经说过我再也不写 ...

  5. POJ1944

    poj1944 一道我不会做的贪心题. (思维才是OI的重点) 但是if您也不会,那就来听我瞎扯吧. 首先,这个图是一个圈,只能连接邻点,使所有求的点联通. 我们先不考虑环,那么就可以想出一个假的做法 ...

  6. HTMLTestRunner.py 文件,已修改完成

    """ A TestRunner for use with the Python unit testing framework. It generates a HTML ...

  7. 将base64Url对应图片保存到本地

    上图中的内容就是base64编码之后对应的Url  图中base64,之前的都是用于声明该图片的格式以及它的编码格式  base64,之后的就是该图片对应的数据了 我们只需要把数据转换为字节保存下来即 ...

  8. django中路由配置的正则

    在django中配置路由遇到正则的坑: django2.x版本中使用re_path来进行正则表达式的匹配 用法如下: from Django.urls import re.path(导入re_path ...

  9. solr(CVE-2019-0193)远程命令执行

    影响版本 Apache Solr < 8.2.0 并且开启了DataImportHandler模块(默认情况下该模块不被启用) 安装 重启daoker  更新配置文件 systemctl dae ...

  10. shell中cmd1 && cmd2 || cmd3的含义

    在某些情况下,很多指令我想要一次输入去执行,而不想要分次去执行时,就要用到 && || 了.cmd 1 && cmd21,若cmd1执行完毕之后且正确执行($?=0), ...