Flink Scala-扩展窗口函数

Flink Scala-扩展窗口函数,scala,apache-flink,flink-streaming,Scala,Apache Flink,Flink Streaming,我正试图弄清楚如何编写自己的WindowFunction,但有一些问题,我不知道为什么。我遇到的问题是apply函数,因为它无法将MyWindowFunction识别为有效输入,因此无法编译。我正在传输的数据包含(时间戳,x,y),其中x和y是0和1,用于测试extractTupleWithouts只返回一个元组(x,y)。我已经用简单的求和和和减少函数成功地运行了代码。感谢您的帮助:)使用Flink 1.3 进口: import org.apache.flink.streaming.api.T

我正试图弄清楚如何编写自己的
WindowFunction
,但有一些问题,我不知道为什么。我遇到的问题是apply函数,因为它无法将
MyWindowFunction
识别为有效输入,因此无法编译。我正在传输的数据包含
(时间戳,x,y)
,其中x和y是0和1,用于测试
extractTupleWithouts
只返回一个元组
(x,y)
。我已经用简单的求和和和减少函数成功地运行了代码。感谢您的帮助:)使用Flink 1.3

进口:

import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.AssignerWithPeriodicWatermarks
import org.apache.flink.streaming.api.scala.function.WindowFunction
import org.apache.flink.streaming.api.watermark.Watermark
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
import org.apache.flink.util.Collector
代码的其余部分:

val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
val text = env.socketTextStream("localhost", 9999).assignTimestampsAndWatermarks(new TsExtractor)
val tuple = text.map( str => extractTupleWithoutTs(str))
val counts = tuple.keyBy(0).timeWindow(Time.seconds(5)).apply(new MyWindowFunction())
counts.print()
env.execute("Window Stream")
MyWindow函数,基本上是复制粘贴示例中的类型更改

class MyWindowFunction extends WindowFunction[(Int, Int), Int, Int, TimeWindow] {
  def apply(key: Int, window: TimeWindow, input: Iterable[(Int, Int)], out: Collector[Int]): () = {
    var count = 0
    for (in <- input) {
      count = count + 1
    }
    out.collect(count)
  }
}
类MyWindowFunction扩展了WindowFunction[(Int,Int),Int,Int,TimeWindow]{ def apply(key:Int,window:TimeWindow,input:Iterable[(Int,Int)],out:Collector[Int]):()={ 变量计数=0
对于(在中,问题是
WindowFunction
的第三个类型参数,即键的类型。该键在
keyBy
方法(
keyBy(0)
中使用索引声明)。因此,无法在编译时确定密钥的类型。如果将密钥声明为字符串,即,
keyBy(“f0”)
,则会出现相同的问题

有两个选项可以解决此问题:

  • 使用
    keyBy
    中的
    KeySelector
    函数提取密钥(类似于
    keyBy(u.\u 1)
    )。编译时已知
    KeySelector
    函数的返回类型,因此可以将正确键入的
    WindowFunction
    Int
    密钥一起使用
  • WindowFunction
    的第三个类型参数的类型更改为
    org.apache.flink.api.java.tuple.tuple
    ,即
    WindowFunction[(Int,Int),Int,org.apache.flink.api.java.tuple.tuple,TimeWindow]
    Tuple
    是由
    keyBy
    提取的密钥的通用持有者。在您的情况下,它将是
    org.apache.flink.api.java.Tuple.Tuple1
    。在
    WindowFunction.apply()
    中,您可以将
    Tuple
    转换为
    Tuple1
    ,并通过
    Tuple1.f0
    访问密钥字段

  • 使用1:使用KeySelector基本上解决了我的问题。之后在MyWindowFunction类中出现了另一个问题。我需要将append函数中的()={..}改为Unit而不是()。非常感谢!还有,谢谢你提供的信息。我试过使用Tuple1。没有任何区别。太好了!很高兴我能帮忙。你说的“没有任何区别”是什么意思?它是否也能正常工作,还是问题仍然存在?抱歉,不清楚。当使用Tuple1时,问题仍然存在。根本不起作用。
    WindowFunction
    必须定义为
    Tuple
    键类型(注意,这必须是Flink的
    Tuple
    类),即
    WindowFunction[(Int,Int),Int,org.apache.flink.api.java.tuple.tuple,TimeWindow]
    。在
    apply()
    方法中,
    tuple
    可以强制转换为
    Tuple1
    (同样,flink的java
    Tuple1
    ,而不是Scala的内置
    Tuple1
    )。