Apache Flink:ProcessWindowFunction不适用

时间:2018-03-20 05:44:36

标签: apache-flink flink-streaming stream-processing

我想在Apache Flink项目中使用ProcessWindowFunction。但是在使用流程函数时出现了一些错误,请参阅下面的代码片段

错误是:

  

WindowedStream,Tuple,TimeWindow>类型中的方法过程(ProcessWindowFunction,R,Tuple,TimeWindow>);不适用于参数(JDBCExample.MyProcessWindows)

我的节目:

DataStream<Tuple2<String, JSONObject>> inputStream;

inputStream = env.addSource(new JsonArraySource());

inputStream.keyBy(0)
  .window(TumblingEventTimeWindows.of(Time.minutes(10)))
  .process(new MyProcessWindows());

我的ProcessWindowFunction

private class MyProcessWindows 
  extends ProcessWindowFunction<Tuple2<String, JSONObject>, Tuple2<String, String>, String, Window>
{

  public void process(
      String key, 
      Context context, 
      Iterable<Tuple2<String, JSONObject>> input, 
      Collector<Tuple2<String, String>> out) throws Exception 
  {
    ...
  }

}

2 个答案:

答案 0 :(得分:5)

问题可能是ProcessWindowFunction的泛型类型。

您正在按位置(keyBy(0))引用该键。因此,编译器无法推断其类型(String),您需要将ProcessWindowFunction更改为:

private class MyProcessWindows 
    extends ProcessWindowFunction<Tuple2<String, JSONObject>, Tuple2<String, String>, Tuple, Window>

通过String替换Tuple,您现在拥有了一个通用占位符,可以在需要访问Tuple1<String>方法中的密钥时转换为processElement()

public void process(
    Tuple key, 
    Context context, 
    Iterable<Tuple2<String, JSONObject>> input, 
    Collector<Tuple2<String, String>> out) throws Exception {

  String sKey = (String)((Tuple1)key).f0;
  ...
}

如果定义KeySelector<IN, KEY>函数来提取密钥,则可以避免强制转换并使用正确的类型,因为编译器已知KEY的返回类型KeySelector

答案 1 :(得分:3)

Fabian所说的:)使用Tuple应该有效,但确实在ProcessWindowFunction中涉及一些丑陋的类型转换。使用KeySelector很容易,并且代码更清晰。 E.g。

.keyBy(new KeySelector<Tuple2<String,JsonObject>, String>() {

    @Override
    public String getKey(Tuple2<String, JsonObject> in) throws Exception {
        return in.f0;
    }
})

上面的内容允许您定义ProcessWindowFunction,如:

public class MyProcessWindows extends ProcessWindowFunction<Tuple2<String, JsonObject>, Tuple2<String, String>, String, TimeWindow> {