Flink存在两种窗口操作,分别为滚动操作和滑动操作,两者主要的区别在于,滚动操作不会重叠,而滑动操作则会让数据产生重叠 。
https://github.com/soniclavier/bigdata-notebook/tree/master/flink/src/main/scala/com/vishnu/flink/streaming
在Streaming应用程序的情况下,数据是连续的,因此我们不能等待在开始处理之前流式传输整个数据。当然,我们可以处理每个传入的事件,然后转移到下一个事件,但在某些情况下,我们需要对传入的数据进行某种聚合 - 例如,有多少用户在过去10分钟内点击了您网页上的链接。在这种情况下,我们必须定义一个窗口并对窗口内的数据进行处理
滚动窗口滚动数据流。这种类型的窗口是不重叠的 - 即,一个窗口中的事件/数据不会在其他窗口中重叠/出现。
你可以配置滚动窗口基于数量,例如基于每5条数据,或者基于时间,例如基于每十秒钟。
滑动窗口与翻滚窗口相对,滑过数据流。因此,滑动窗口可以重叠,它可以对输入的数据流进行更平滑的聚合 - 因为您不是从一组输入跳转到下一组输入,而是滑过输入的数据流。
与滚动窗口类似,您也可以根据时间或事件计数配置滑动窗口。
下面的示例显示了一个字数统计程序,它监听套接字并计算窗口内每个字接收的次数。这里的窗口基于计数,每5件物品就会翻滚。
Below example shows a word count program that listens to a socket and counts the number of times each word is received within a window. The window here is based on count and it tumbles for every 5 items.
object CountTumblingWindow {
def main(args: Array[String]) {
val sev = StreamExecutionEnvironment.getExecutionEnvironment
val socTextStream = sev.socketTextStream("localhost",4444) //read from socket
val counts = socTextStream.flatMap{_.split("\\s")} //split sentence into words
.map { (_, 1) } //emit 1 for each word
.keyBy(0) //group based on word
.countWindow(5) //window for every 5 items in the group
.sum(1)
.setParallelism(4); //setting parallelism (optional)
counts.print()
sev.execute()
}
}
在上面的示例中,每5条数据触发一次窗口。由于我们正在执行keyby,因此每个窗口将只包含同一组的单词。
e.g.,
if stream is : one two one two one two one two one
window1 = {one,one,one,one,one}
window2 = {two,two,two,two}
window1 will triggered but not window 2, it need one more 'two' to reach count 5.
In the below example, the window slides every 10 seconds and the width of the window is 15 seconds of data. Therefore, there is an overlap between the windows.
object TimeSlidingWindow {
def main(args: Array[String]) {
val sev = StreamExecutionEnvironment.getExecutionEnvironment
val socTextStream = sev.socketTextStream("localhost",4444)
val counts = socTextStream.flatMap{_.split("\\s")}
.map { (_, 1) }
.keyBy(0)
.timeWindow(Time.seconds(15),Time.seconds(10))
.sum(1).setParallelism(4);
counts.print()
sev.execute()
}
}
这涵盖了Flink中Windows类型的基础知识。我们可以在Flink中执行各种复杂的窗口操作 - 例如,我们可以选择基于时间滑动窗口,但是根据项目计数触发执行,并且还选择在当前窗口中保留少量项目用于下一个窗口处理。我将尝试在即将发布的博客中介绍这些高级主题。