在Flink中,流窗口似乎不起作用?

时间:2015-05-26 14:44:42

标签: apache-flink

我尝试增强显示流使用情况的Flink示例。 我的目标是使用窗口功能(请参阅window函数调用)。 我假设下面的代码输出流的最后3个数字的总和。 (由于ubuntu上的nc -lk 9999,流被打开) 实际上,输出总结了输入的所有数字。切换到时间窗口会产生相同的结果,即不会产生窗口。

这是一个错误吗? (使用的版本:github上的最新版本)

object SocketTextStreamWordCount {
  def main(args: Array[String]) {
    val hostName = args(0)
    val port = args(1).toInt
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    // Create streams for names and ages by mapping the inputs to the corresponding objects
    val text = env.socketTextStream(hostName, port)    
    val currentMap = text.flatMap { (x:String) => x.toLowerCase.split("\\W+") }
    .filter { (x:String) => x.nonEmpty }      
    .window(Count.of(3)).every(Time.of(1, TimeUnit.SECONDS))
    //  .window(Time.of(5, TimeUnit.SECONDS)).every(Time.of(1, TimeUnit.SECONDS))
      .map { (x:String) => ("not used; just to have a tuple for the sum", x.toInt) }

    val numberOfItems = currentMap.count
    numberOfItems print
    val counts = currentMap.sum( 1 )
    counts print

    env.execute("Scala SocketTextStreamWordCount Example")
  }
}

1 个答案:

答案 0 :(得分:5)

问题似乎是从WindowedDataStreamDataStream的隐式转换。此隐式转换会在flatten()上调用WindowedDataStream

在您的情况下会发生的是代码扩展到此:

val currentMap = text.flatMap { (x:String) => x.toLowerCase.split("\\W+") }
    .filter { (x:String) => x.nonEmpty }      
    .window(Count.of(3)).every(Time.of(1, TimeUnit.SECONDS))
    .flatten()   
    .map { (x:String) => ("not used; just to have a tuple for the sum",x.toInt) }    

flatten()的作用类似于集合上的flatMap()。它需要窗口流,可以看作是集合的集合([[a,b,c], [d,e,f]]),并将其转换为元素流:[a,b,c,d,e,f]

这意味着您的计数实际上只对已经窗口化的原始流进行操作,并且"去窗口"。这看起来根本就没有窗口。

这是一个问题,我会立即解决这个问题。 (我是Flink提交者之一。)您可以在此处跟踪进度:https://issues.apache.org/jira/browse/FLINK-2096

使用当前API执行此操作的方法是:

val currentMap = text.flatMap { (x:String) => x.toLowerCase.split("\\W+") }
    .filter { (x:String) => x.nonEmpty }   
    .map { (x:String) => ("not used; just to have a tuple for the sum",x.toInt) }    
    .window(Count.of(3)).every(Time.of(1, TimeUnit.SECONDS))

WindowedDataStream有一个sum()方法,因此不会隐式插入flatten()调用。不幸的是,count()上没有WindowedDataStream,因此您必须手动将1字段添加到元组并计算这些字段。