从时间窗口的键控流我想得到目前为止看到的最大窗口的流(在元素数量方面最大)。
目前我有以下代码:
source
.keyBy(...)
.timeWindow(...)
.fold((DummyKey, 0)) { case ((_, current), key) => (key, current + 1) }
.keyBy(_ => ())
.maxBy(1)
fold
的结果是(key, count)
个元素的流 - 所以从这个流中,我想得到一个“最高计数密钥”的更新流。
keyBy(_ => ())
- 因为这是一个全局操作),并使用maxBy
- 这个几乎工作:我得到一个流最高计数,但每个元素的当前最高计数。
我认为我正在寻找的是某种filter-with-previous值,只有在新值与之前的值不同时才会发出元素。
目前Flink有可能吗?
答案 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>