Apache Flink在流数据上计算分位数[在scala中]

时间:2018-08-02 16:55:23

标签: scala apache-flink flink-streaming

我想使用Scala在Flink中计算流数据的分位数。我的问题类似于flink calculate median on stream,但比这个问题简单。我认为可以通过定义自定义聚合函数来完成,但是我一直在寻找一些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个百分位数。有没有办法我可以使用FlatMap做到这一点?如果我们能说

那就太好了
events.map(_.stat1).quantile(0.95)

但是我知道今天没有内置的分位数功能。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

要对整个流进行完全准确的分位数/百分位数计算,需要使整个流保持状态,而这是完全不可扩展的。我建议改用t-digest sketch之类的方法进行估算。

我不知道有人用Flink做到这一点,但这应该相当简单。