如何在flink中使用delta触发器?

时间:2017-12-05 20:03:07

标签: scala apache-flink flink-streaming

我想在apache flink中使用deltatrigger(flink 1.3),但是我对这段代码有些麻烦:

.trigger(DeltaTrigger.of(100, new DeltaFunction[uniqStruct] {
    override def getDelta(oldFp: uniqStruct, newFp: uniqStruct): Double = newFp.time - oldFp.time
  }, TypeInformation[uniqStruct]))

我有这个错误:

error: object org.apache.flink.api.common.typeinfo.TypeInformation is not a value [ERROR] }, TypeInformation[uniqStruct]))

我不明白为什么DeltaTrigger需要TypeSerializer[T] 我不知道该怎么做才能消除这个错误。

非常感谢大家。

2 个答案:

答案 0 :(得分:0)

我会读到这一点https://ci.apache.org/projects/flink/flink-docs-release-1.2/dev/types_serialization.html听起来你可以在类型信息上使用typeInfo.createSerializer(config)创建一个序列化器。请注意您当前传入的内容类型本身,而不是类型信息,这就是您获得错误的原因。

你需要做更像

的事情
val uniqStructTypeInfo: TypeInformation[uniqStruct] = createTypeInformation[uniqStruct]
val uniqStrictTypeSerializer = typeInfo.createSerializer(config)

引用上面有关配置参数的页面,您需要传递以创建序列化程序

  

config参数的类型为ExecutionConfig并保存   有关该程序的已注册自定义序列化程序的信息。哪里   永远可能,尝试传递正确的ExecutionConfig程序。您   通常可以通过调用从DataStream或DataSet获取它   getExecutionConfig()。内部函数(如MapFunction),你可以得到   它通过使函数成为Rich函数和调用   getRuntimeContext()。getExecutionConfig()。

答案 1 :(得分:0)

DeltaTrigger需要TypeSerializer,因为它使用Flink的托管状态机制来存储每个元素,以便稍后与下一个元素进行比较(它只保留一个元素,最后一个元素,作为新元素更新)到达)。

您将找到一个示例(使用Java)here

但是如果您只需要一个每100毫秒触发一次的窗口,那么使用TimeWindow会更容易,例如

input
  .keyBy(<key selector>)
  .timeWindow(Time.milliseconds(100)))
  .apply(<window function>)

更新:

要让每100毫秒触发一小时的窗口,您可以使用滑动窗口。但是,您将拥有10 * 60 * 60个窗口,并且每个事件都将放入这36000个窗口中的每个窗口中。所以这不是一个好主意。

如果您使用带有GlobalWindow的{​​{1}},则只有当事件超过100毫秒时才会触发该窗口,这不是您所说的。

我建议你看看ProcessFunction。以这种方式得到你想要的东西应该很简单。