目录
1、窗口
-
在流处理应用中,数据是连续不断的,因此我们不可能等到所有数据都到了才开始处理。
-
当然我们可以每来一个消息就处理一次,但是有时我们需要做一些聚合类的处理,例如:在过去的1分钟内有多少用户点击了我们的网页。
-
在这种情况下,我们必须定义一个窗口,用来收集最近一分钟内的数据,并对这个窗口内的数据进行计算。
-
窗口可以是基于时间驱动的(Time Window,例如:每30秒钟)
-
也可以是基于数据驱动的(Count Window,例如:每一百个元素)
-
同时基于不同事件驱动的窗口又可以分成以下几类:
- 翻滚窗口 (Tumbling Window, 无重叠)
- 滑动窗口 (Sliding Window, 有重叠)
- 会话窗口 (Session Window, 活动间隙)
- 全局窗口 (略)
1.1 翻滚窗口(Tumbling Window, 无重叠)
-
翻滚窗口能将数据流切分成不重叠的窗口,每一个事件只能属于一个窗口
-
翻滚窗具有固定的尺寸,不重叠。
-
示例:
- 定义样例类:水位传感器:用于接收空高数据,id 传感器编号,ts 时间戳,vc 空高
- 使用flink 窗口函数 tumbling(滚动窗口) 窗口周期 10秒,找出每个传感器的最小空高
- 从socket端口接收字符串格式为"ws_001, 1577844001, 45.0" DataStream[String]
- 接收到字符串后将字符串流转换成WaterSensor流 DataStream[WaterSensor]
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
object WindowDemo1 {
def main(args: Array[String]): Unit = {
val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1) //设置并行度
val stream: DataStream[String] = env.socketTextStream("192.168.136.20",7777)
val dataStream: DataStream[WaterSensor] = stream.map(x => {
val strings: Array[String] = x.split(",")
WaterSensor(strings(0), strings(1).trim.toLong, strings(2).trim.toDouble)
})
val dataStream2: DataStream[(String, Double)] = dataStream.map(data => (data.id, data.vc))
val dataStream3: KeyedStream[(String, Double), String] = dataStream2.keyBy(_._1) //按元组第一个元素分组
//点进KeyedStream,快捷键Alt+7 查看类所有的方法
//加滚动窗口,窗口时长10秒,Tumbling窗口
val dataStream4: WindowedStream[(String, Double), String, TimeWindow] = dataStream3.timeWindow(Time.seconds(10))
val minDataStream: DataStream[(String, Double)] = dataStream4.reduce((x,y)=>(x._1,x._2.min(y._2)))
dataStream.print("orgion") //为了方便查看,打印原始数据的流
minDataStream.print("min")
env.execute("windowDemo1")
}
/**
* 定义样例类:水位传感器:用于接收空高数据
*
* @param id 传感器编号
* @param ts 时间戳
* @param vc 空高
*/
case class WaterSensor(id: String, ts: Long, vc: Double)
}
开启socket端口:nc -lk 7777
输入如下测试数据:会按照事件处理时间进行窗口聚合,下面会详细说明flink的三种时间。
ws_001, 1609314670, 45.0
ws_002, 1609314671, 33.0
ws_003, 1609314672, 32.0
ws_002, 1609314673, 23.0
ws_003, 1609314674, 31.0
ws_002, 1609314675, 45.0
ws_003, 1609314676, 18.0
ws_002, 1609314677, 34.0
ws_003, 1609314678, 47.0
ws_001, 1609314679, 55.0
ws_001, 1609314680, 25.0
ws_001, 1609314681, 25.0
ws_001, 1609314682, 25.0
ws_001, 1609314683, 26.0
ws_001, 1609314684, 21.0
ws_001, 1609314685, 24.0
ws_001, 1609314686, 15.0
ws_001, 1609314687, 15.0
1.2 滑动窗口 (Sliding Window, 有重叠)
- 滑动窗口和翻滚窗口类似,区别在于:滑动窗口可以有重叠的部分。
- 在滑窗中,一个元素可以对应多个窗口。
还是上面的例子,找出每个传感器的最小空高,窗口周期是10秒,滑动时间是5秒。
import org.apache.flink.streaming.api