flink笔记7 Flink时间语义和Window

Catalog

Flink的三种时间语义

Window

Window API


Flink的三种时间语义

  • 事件生成时间 Event time  :事件自身的时间,一般就是数据本身携带的时间
  • 事件接入时间 Ingestion time :事件进入Flink的时间,在数据源操作处(进入 Flink source 时),每个事件将进入 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 Fail over to rm2

       Event time :2017-11-02 18:37:15.624

Ingestion time :2017-11-12 10:00:00.123     

Processing time:2017-11-12 10:00:01.234 

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

如果要使用EventTime,那么需要引入EventTime的时间属性,引入EventTime的方法:                                                                                                                                                                                     

val env = StreamExecutionEnvironment.getExecutionEnvironment

//从调用时刻开始给env创建的每一个stream追加时间内特性
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)

Window

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

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

窗口window是从 Streaming(流) 到 Batch(批) 的一个桥梁。

Window可以是时间驱动的:Time Window(时间窗口):按照时间生成Window;也可以是数据驱动的:Count Window(计数窗口):按照指定的数据条数生成一个Window,与时间无关

Window的分类

  • Tumbling Window(滚动窗口)  窗口长度固定,没有重叠

  • Sliding Window(滑动窗口)  窗口长度固定,可以有重叠

  • Session Window(会话窗口)  时间无对齐

滚动窗口:将数据依据固定的窗口长度对数据进行切片

翻滚窗口能将数据流切分成不重叠的窗口,每一个事件只能属于一个窗口。窗口左闭右开[  )

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

滑动窗口和翻滚窗口类似,区别在于:滑动窗口可以有重叠的部分。

会话窗口:由一系列事件组合一个指定的时间长度的timeout间隙组成,一段时间没有接收新数据就会生成新的窗口

没有固定的开始时间和结束时间,只有当一段时间内没有接收新数据就会关闭窗口,下次来新数据的时候开启新窗口。

本质还是TimeWindow,将某段时间内活跃度比较高的数据聚合成一个窗口进行计算,窗口触发的条件是Session Gap,Session Gap规定了不活跃数据的时间上限。

 

Window API

创建一个窗口(可以基于这个window去做一些聚合或者其他操作)

  • 通用方法 .window()   window方法必须在keyBy()之后才能用
  • 简单方法 .timeWindow()    .countWindow()  不能用来创建会话窗口

window()方法接收的输入参数是一个WindowAssigner,它负责将每一条输入的数据分发到正确的window中

Flink提供了通用的WindowAssigner

  • Tumbling window
  • Sliding window
  • Session window
  • Global window 

Global window将所有相同key的数据分配到单个窗口中计算结果,窗口没有起始和结束时间,窗口需要借助trigger来触发计算。还需要有指定的数据清理机制,否则数据将一直留在内存中。所有的窗口都会在同一个task中计算,也就是并行度parallesim 为1,Global window不常用。

window方法创建窗口的代码实现:

import org.apache.flink.streaming.api.scala.{StreamExecutionEnvironment, createTypeInformation}
import org.apache.flink.streaming.api.windowing.assigners.{SlidingEventTimeWindows, SlidingProcessingTimeWindows, TumblingEventTimeWindows, TumblingProcessingTimeWindows}
import org.apache.flink.streaming.api.windowing.time.Time

case class sensorReading(id:String,timestamp:Long,temperature:Double)

object window_test {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

    val inputdatastream = env.socketTextStream("localhost",7777)

    val data_stream = inputdatastream
      .map ( data => {
        val arr = data.split(",")
        sensorReading(arr(0), arr(1).toLong, arr(2).toDouble)
      }
      )

    val result_stream = data_stream
      .map(data =>(data.id,data.timestamp,data.temperature))
      .keyBy(_._1)
      //window Assigner
//      Tumbling Time Window 第一个参数代表:size 第二个参数代表:offset 延迟
//      .window(TumblingEventTimeWindows.of(Time.seconds(10)))
//      .window(TumblingEventTimeWindows.of(Time.seconds(10),Time.seconds(5)))

//      .window(TumblingProcessingTimeWindows.of(Time.seconds(10)))
//      .window(TumblingProcessingTimeWindows.of(Time.seconds(10),Time.seconds(5)))


//      Sliding Time Window 第一个参数代表:size 第二个参数代表:slide 第三个参数代表:offset
//      .window(SlidingEventTimeWindows.of(Time.seconds(10),Time.seconds(5)))
//      .window(SlidingEventTimeWindows.of(Time.seconds(10),Time.seconds(5),Time.seconds(2)))
      .window(SlidingProcessingTimeWindows.of(Time.seconds(10),Time.seconds(5)))
//      .window(SlidingProcessingTimeWindows.of(Time.seconds(10),Time.seconds(5),Time.seconds(2)))
    
//   经过windowFunction变成DataStream类型才可以print 现在是一个windowedStream
    //windowFunction
      .reduce((data1,data2)=>(data1._1,data2._2,data1._3.min(data2._3)))
//    result_stream.print()

    env.execute("window test")
  }
}

参数、方法使用可以参考底层源码,例如

SlidingProcessingTimeWindows类的静态方法可以返回一个SlidingProcessingTimeWindows类型的对象,两个参数均是Time类型,第一个参数是窗口大小,第二个参数是窗口滑动时间,和另一个方法相比,第三个参数默认offset:0

简单方法创建窗口的代码实现:

import org.apache.flink.streaming.api.scala.{StreamExecutionEnvironment, createTypeInformation}
import org.apache.flink.streaming.api.windowing.time.Time

object window_test2 {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
//    env.setParallelism(1)

    val inputdatastream = env.socketTextStream("localhost",7777)

    val data_stream = inputdatastream
      .map ( data => {
        val arr = data.split(",")
        sensorReading(arr(0), arr(1).toLong, arr(2).toDouble)
      }
      )

    val result_stream = data_stream
      .map(data =>(data.id,data.timestamp,data.temperature))
      .keyBy(_._1)
//      这两个方法 一个参数代表滚动窗口Tumbling,两个参数代表滑动窗口sliding
      .timeWindow(Time.seconds(10))
//      .timeWindow(Time.seconds(10),Time.seconds(5))
//      .countWindow(10)
//      .countWindow(10,5)
      .reduce((data1,data2)=>(data1._1,data2._2,data1._3.min(data2._3)))

    result_stream.print()
    env.execute("window test2")
  }
}
输入数据
输出数据

 

window operate = window assigner + window function

窗口函数Window Function   --定义了对窗口中收集的数据做的计算操作

  • 增量聚合函数(incremental aggregation functions)

来一个就计算一个

ReduceFunction, AggregateFunction, FoldFunction

主要基于中间状态的计算结果,窗口中只维护中间结果状态值,不缓存原始数据。

 

  • 全窗口函数(full window functions)

先把窗口内所有数据收集起来,等到计算的时候遍历所有数据

ProcessWindowFunction

全量窗口函数使用的代价相对较高,性能比较弱,主要因为此时算子需要对所有属于该窗口的介入数据进行缓存,然后等到窗口触发的时候,对所有的原始数据进行汇总计算。如果接入数据量比较大或窗口时间比较长,就比较有可能导致计算性能的下降。

其它可选窗口API

  • .allowedLateness() —— 允许处理迟到的数据
  • .sideOutputLateData() —— 将迟到的数据放入侧输出流
  • .getSideOutput() —— 获取侧输出流
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值