window()方法必须在keyBy之后才能用,为keyStream的api
CountWindow
CountWindow根据窗口中相同key元素的数量来触发执行,执行时只计算元素数量达到窗口大小的key对应的结果。
注意: CountWindow的window_size指的是相同Key的元素的个数,不是输入的所有元素的总数。
滚动窗口
默认的CountWindow是一个滚动窗口,只需要指定窗口大小即可,当元素数量达到窗口大小时,就会触发窗口的执行。
object Window01 {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
val stream = env.socketTextStream("note01",8888)
val streamKeyBy = stream.map(item => (item ,1L)).keyBy(0)
//这里 countWindow 可以传递一个参数 滚动窗口,两个参数为滑动窗口
streamKeyBy.countWindow(5).reduce(
(item1,item2) => (item1._1,item1._2+item2._2)
).print()
env.execute("结果:")
}
}
这里指的是单个相同的key达到5条进行统计.不是消息的个数达到5条
滑动窗口
滑动窗口和滚动窗口的函数名是完全一致的,只是在传参数时需要传入两个参数,一个是window_size,一个是sliding_size。
下面代码中的sliding_size设置为了2,也就是说,每收到两个相同key的数据就计算一次,每一次计算的window范围是5个元素。
package window
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.api.scala._
object Window01 {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
val stream = env.socketTextStream("note01",8888)
val streamKeyBy = stream.map(item => (item ,1L)).keyBy(0)
//滑动窗口大小为5.步长为2
streamKeyBy.countWindow(5,2).reduce(
(item1,item2) => (item1._1,item1._2+item2._2)
).print()
env.execute("结果:")
}
}
达到滑动步长的时候计算一次,达到滑动窗口大小的时候计算一次
TimeWindow
TimeWindow是将指定时间范围内的所有数据组成一个window,一次对一个window里面的所有数据进行计算。
滚动窗口
Flink默认的时间窗口根据Processing Time 进行窗口的划分,将Flink获取到的数据根据进入Flink的时间划分到不同的窗口中。
package window
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time
object Window01 {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
val stream = env.socketTextStream("note01",8888)
val streamKeyBy = stream.map(item => (item ,1L)).keyBy(0)
streamKeyBy.timeWindow(Time.seconds(3)).reduce(
(item1,item2) => (item1._1,item1._2+item2._2)
).print()
env.execute("结果:")
}
}
滑动窗口
滑动窗口和滚动窗口的函数名是完全一致的,只是在传参数时需要传入两个参数,一个是window_size,一个是sliding_size。
时间间隔可以通过Time.milliseconds(x),Time.seconds(x),Time.minutes(x)等其中的一个来指定。
package window
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time
object Window01 {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
val stream = env.socketTextStream("note01",8888)
val streamKeyBy = stream.map(item => (item ,1L)).keyBy(0)
streamKeyBy.timeWindow(Time.seconds(10),Time.seconds(2)).reduce(
(item1,item2) => (item1._1,item1._2+item2._2)
).print()
env.execute("结果:")
}
}
增量聚合函数:每条数据到来就进行计算,保持一个简单的状态
ReduceFunction,AggregateFunction
全窗口函数:先把窗口所有数据收集起来,等到计算的时候会遍历所有数据
ProcessWindowFunction
其他可选API
放在window后面
trigger() : 触发器,定义window什么时候关闭,触发计算并输出结果
evitor() : 移除器:定义移除某些数据的逻辑
allowedLateness() : 允许处理迟到的数据
sideOutputLateData() : 将迟到的数据放入侧输出流
getSideOutput() : 获取侧输出流