我想使用Scala在Flink中计算流数据的分位数。我的问题类似于但比这更简单的是计算流中的中值。我认为这可以通过定义一个自定义聚合函数来实现,但我正在寻找一些Scala的例子。我看过中的例子https://github.com/dataArtisans/flink-training-exercises但没有完全找到我要找的东西。我计算了总和,计算了平均值,我想计算第95个百分位数。
val nwStream = env
// TestData topic is our Kafka topic
.addSource(kafkaConsumer)
// configure timestamp and watermark assigner
.assignTimestampsAndWatermarks(new TestDataTSAssigner)
// group by stats by
.keyBy(_.sSomeId)
// sliding window is 5 minutes long and slides every 1 minute
.timeWindow(Time.minutes(5), Time.minutes(1))
.apply { (key: String, window: TimeWindow, events: Iterable[TestData],
out: Collector[(String, Long, Long, Double, Double)]) =>
out.collect((key, window.getEnd, events.size,
events.map(_.stat1).sum/events.size,
events.map(_.stat2).sum/events.size)
}
我希望能够在collect函数中以类似的方式计算第95个百分位数。有没有什么方法可以用平面图来做这件事?如果我们能说,那就太棒了
events.map(_.stat1).quantile(0.95)
但据我所知,目前还没有内置的分位数函数。
任何帮助都将不胜感激。
在整个流中进行完全准确的分位数/百分位数计算需要保持整个流处于状态,这根本不可扩展。我建议使用类似t-摘要的草图来进行估计。
我不知道有谁用Flink做过这件事,但它应该相当简单。