Flink中最大时间窗口的更新流

时间:2016-10-22 14:13:45

标签: apache-flink flink-streaming

从时间窗口的键控流我想得到目前为止看到的最大窗口的流(在元素数量方面最大)。

目前我有以下代码:

source
  .keyBy(...)
  .timeWindow(...)
  .fold((DummyKey, 0)) { case ((_, current), key) => (key, current + 1) }
  .keyBy(_ => ())
  .maxBy(1)

fold的结果是(key, count)个元素的流 - 所以从这个流中,我想得到一个“最高计数密钥”的更新流。

然后我按一个常量键{(keyBy(_ => ()) - 因为这是一个全局操作),并使用maxBy - 这个几乎工作:我得到一个流最高计数,但每个元素的当前最高计数。

我认为我正在寻找的是某种filter-with-previous值,只有在新值与之前的值不同时才会发出元素。

目前Flink有可能吗?

1 个答案:

答案 0 :(得分:2)

默认情况下,Flink没有这样的过滤器,但是自己实现它应该相当容易。

您可以使用类似于此的有状态FlatMap执行此操作:

val source: DataStream[Int] = ???

source
  .keyBy(_: Int => _)
  .timeWindow(Time.minutes(10))
  .fold((1, 0)) { case ((_, current), key) => (key, current + 1) }
  // move everything to the same key
  .keyBy(_ => 0) 
  // use stateful flatmap to remember highest count and filter by that
  .flatMapWithState( (in, state: Option[Int]) => 
    // filter condition
    if (in._2 > state.getOrElse(-1)) 
      // emit new value and update max count
      (Seq(in), Some(in._2)) 
    else 
      // emit nothing (empty Seq()) and keep count
      (Seq(), state)
  ).setParallelism(1)

如果非并行(单线程)过滤器运算符成为瓶颈,您可以通过添加带有随机密钥的keyBy和具有更高并行度的有状态过滤器FlatMap来添加并行预过滤器。 / p>