Flink_windowApi

一:Window 是无限数据流处理的核心,Window 将一个无限的stream 拆分成有限大小的”buckets”桶,我们可以在这些桶上做计算操作。就是无界流转换有界流。可以理解为数据经过winow后都有了时间属性,当再做其他操作是这个数据就可能属于不同的数据集。
窗口分类
TimeWindow 滚动 滑动 会话(一段时间没有数据就关 重新开窗)超时时间 时间不对齐 只有时间会话窗口)
CountWindow 滚动 滑动
二:滚动窗口 先分组 再开窗 在这里插入图片描述
三:滑动窗口:
在这里插入图片描述
四会话窗口
在这里插入图片描述
调用时先分组 KeyedStream
窗口只是对数据进行分组 不做处理。
流式数据又变成集合 关窗后才有操作。但是窗口内一直在操作。

窗口分配器
def window[W <: Window](assigner: WindowAssigner[_ >: T, W]): WindowedStream[T, K, W] = {
new WindowedStream(new WindowedJavaStream[T, K, W](javaStream, assigner))
}
增量聚合函数(incremental aggregation functions) reduce/aggregate
全窗口函数(full window functions) fold/apply
package com.atguigu.window

import com.atguigu.sourceandsink.SensorReading
import org.apache.flink.streaming.api.scala.{DataStream, KeyedStream, StreamExecutionEnvironment, WindowedStream}
import org.apache.flink.streaming.api.windowing.assigners.{EventTimeSessionWindows, SlidingProcessingTimeWindows, TumblingEventTimeWindows}
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.{GlobalWindow, TimeWindow}
import org.apache.flink.streaming.api.scala._

object TestWindow {
def main(args: Array[String]): Unit = {
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
val dataStream: DataStream[String] = env.readTextFile(“in/sensor.txt”)
val ds: DataStream[SensorReading] = dataStream.map(data => {
val arr: Array[String] = data.split(",")
SensorReading(arr(0), arr(1).toLong, arr(2).toDouble)
})
val keyStream= ds.map(data => (data.id,data.temperature,data.timestamp)).keyBy(_._1)
//按照id分组 先分组再开窗 定义一个15s的滚动窗口 偏移量为3s
//定义滚动窗口
val tumblingWindow= keyStream.window(TumblingEventTimeWindows.of(Time.seconds(15),Time.seconds(3)))
//定义滑动窗口
val slidingWindow= keyStream.window(SlidingProcessingTimeWindows.of(Time.seconds(15),Time.seconds(3)))
//会话窗口 如果两个数据间隔大于10s 划分到两个窗口 否则在一个窗口
val sessionWindow= keyStream.window(EventTimeSessionWindows.withGap(Time.seconds(10)))
//简写方式 传入一个参数就是滚动时间窗口 两个参数就是滑动时间窗口
val timeWindow= keyStream.timeWindow(Time.seconds(2))
val countWindow = keyStream.countWindow(10)
//窗口只是对数据进行分桶 并未对数据进行具体处理
//窗口函数
//1.增量聚合函数
//统计每15s内 按照id分组后每个传感器的最低温度
val stream = timeWindow.minBy(1)
//取出每个传感器每15s的温度最低值
val reduceStream: DataStream[(String, Double, Long)] = timeWindow.reduce((curDate,newDate)=>(curDate._1,curDate._2,curDate._3.min(newDate.3)))
reduceStream.print()
env.execute()
//2.全量聚合函数
}
}
五:窗口就是将无限流切割为有限流的一种方式,将数据分发到有限大小的桶(bucket)中进行分析。并未对数据进行具体处理,只是对数据进行分桶。窗口后要加窗口函数 :1.增量聚合窗口。每条数据来就计算一次。优势:快。reduceFunction.timeWindow.aggregate()
2.全量聚合窗口。将窗口内所有数据收集起来,再做计算。批处理。(窗口内排序)ProcessWindowFunction
dataStream—>keyStream—>windowStream---->dataStream
六:窗口类型 基于Processing Time
1:时间窗口Time Window
a 滚动时间窗口(Tumbling Windows) 长度固定 没有重叠
val tumblingWindow= keyStream.window(TumblingEventTimeWindows.of(Time.seconds(15))
b 滑动时间窗口 (Slinding Windows)长度固定 可以重叠
val slidingWindow= keyStream.window(SlidingProcessingTimeWindows.of(Time.seconds(15),Time.seconds(3)))
c 会话窗口(Seddion Windows)时间不对齐,按照时间间隔划分窗口。一段时间没有收到数据就产生新的窗口。
//超时时间 如果数据来的时间间隔小于10s 就在一个窗口里面 大于10s 就在两个窗口
val sessionWindow= keyStream.window(EventTimeSessionWindows.withGap(Time.seconds(10)))
val sessionWindowStream: WindowedStream[(String, Double, Long), String, TimeWindow] = keyStream.window(EventTimeSessionWindows.withGap(Time.minutes(10)))
简写方式:
keyStream.timeWindow(Time.seconds(10),Time.seconds(3)) //滑动窗口
keyStream.timeWindow(Time.seconds(10)) //滚动窗口
keyStream.countWindow(10) //滚动计数窗口
keyStream.countWindow(10,3) //滑动计数窗口
2.计数窗口Count Window.
七:API调用
1.先分组。得到keyStream> 按照传感器的ID分组。得到keyStream数据流。
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
val dataStream: DataStream[String] = env.readTextFile(“in/sensor.txt”)
val ds: DataStream[SensorReading] = dataStream.map(data => {
val arr: Array[String] = data.split(",")
SensorReading(arr(0), arr(1).toLong, arr(2).toDouble)
})
val keyStream= ds.map(data => (data.id,data.temperature,data.timestamp)).keyBy(
._1)
2.再开窗
val timeWindow= keyStream.timeWindow(Time.seconds(15))
//取出每个传感器每15s的温度最低值 当前时间的最低温度值
val reduceDataStream: DataStream[(String, Double, Long)] = timeWindow.reduce((curRes,newData)=> (curRes._1,curRes._2.min(newData._2),curRes._3))
nc -L -p 7777
val dataStream: DataStream[String] = env.socketTextStream(“localhost”,7777)
八:扩展
.trigger() 触发器。定义window什么时候关闭,触发计算并输出结果。
.evictor() 移出器。定义移除某些数据的逻辑。
.allowedLateness() 允许处理迟到的数据
.sideOutputLateDate() 将迟到的数据放入到侧输出流。
.getSideOutput() 获取侧输出流。

成功代码
//需求 输出每15s内各个传感器的最低温度
// 通过nc 获得数据源
//基于处理时间。
//每15s开一个窗口
package com.atguigu.window

import com.atguigu.sourceandsink.SensorReading
import org.apache.flink.api.common.functions.ReduceFunction
import org.apache.flink.streaming.api.scala.{DataStream, KeyedStream, StreamExecutionEnvironment, WindowedStream}
import org.apache.flink.streaming.api.windowing.assigners.{EventTimeSessionWindows, SlidingProcessingTimeWindows, TumblingEventTimeWindows}
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.{GlobalWindow, TimeWindow}
import org.apache.flink.streaming.api.scala._

object TestWindow {
def main(args: Array[String]): Unit = {
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
val dataStream: DataStream[String] = env.socketTextStream(“localhost”,7777)
//val dataStream: DataStream[String] = env.readTextFile(“in/sensor.txt”)
val ds: DataStream[SensorReading] = dataStream.map(data => {
val arr: Array[String] = data.split(",")
SensorReading(arr(0), arr(1).toLong, arr(2).toDouble)
})
val keyStream: KeyedStream[(String, Double, Long), String] = ds.map(data =>(data.id,data.temperature,data.timestamp)).keyBy(_.1)
// //val keyStream= ds.map(data => (data.id,data.temperature,data.timestamp)).keyBy(
._1)
//按照id分组 先分组再开窗 定义一个15s的滚动窗口 偏移量为3s
//定义滚动窗口
val tumblingWindow= keyStream.window(TumblingEventTimeWindows.of(Time.seconds(15)))
//定义滑动窗口
val slidingWindow= keyStream.window(SlidingProcessingTimeWindows.of(Time.seconds(15),Time.seconds(3)))
//会话窗口 如果两个数据间隔大于10s 划分到两个窗口 否则在一个窗口
val sessionWindow= keyStream.window(EventTimeSessionWindows.withGap(Time.seconds(10)))
//简写方式 传入一个参数就是滚动时间窗口 两个参数就是滑动时间窗口
val timeWindow= keyStream.timeWindow(Time.seconds(15))
keyStream.timeWindow(Time.seconds(10),Time.seconds(3))
val countWindow = keyStream.countWindow(10)
keyStream.countWindow(10,3)
val sessionWindowStream: WindowedStream[(String, Double, Long), String, TimeWindow] = keyStream.window(EventTimeSessionWindows.withGap(Time.minutes(10)))
//窗口只是对数据进行分桶 并未对数据进行具体处理
//窗口函数
//1.增量聚合函数
//统计每15s内 按照id分组后每个传感器的最低温度
// timeWindow.reduce(new MyReduce())
val stream = timeWindow.minBy(1)
//取出每个传感器每15s的温度最低值 当前时间的最低温度值
val reduceDataStream: DataStream[(String, Double, Long)] = timeWindow.reduce((curRes,newData)=>(curRes._1,curRes._2.min(newData._2),curRes._3))
val reduceStream: DataStream[(String, Double, Long)] = timeWindow.reduce((curDate,newDate)=>(curDate._1,curDate._2,curDate._3.min(newDate._3)))
reduceStream.writeAsCsv(“out4/”)

reduceStream.print("mapredufe")
env.execute()
//2.全量聚合函数

}
}
class MyReduce extends ReduceFunction[SensorReading]{
override def reduce(value1: SensorReading, value2: SensorReading): SensorReading = {
SensorReading(value1.id,value2.timestamp,value1.temperature.min(value2.temperature))
}
}
增量聚合函数 统计最大值 求和
ReduceFunction AggregateFunction
全窗口聚合函数 排序 ProcessWindowFunction WindowFunction

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值