寻找windowAll()的替代形式,将数据保存在同一节点上以进行聚合

时间:2017-08-05 01:23:58

标签: apache-flink

我有一个高度并行化的聚合,我在多个节点上运行了很多键。然后,我想要对所有值进行汇总聚合,类似于下面的代码:

val myStream = sourceStream
  .keyBy( 0 )    
  .window(TumblingProcessingTimeWindows.of(Time.minutes(5)))          
  .reduce(_ + _)
  .addSink(new OtherSink)

val summaryStream = myStream
  .map(Row.fromOtherRow(_))
                     // parallelism is 1 by definition
  .windowAll(TumblingProcessingTimeWindows.of(Time.minutes(5)))   
  .reduce(_ + _)
  .addSink(new RowSink)

这很好用,但我注意到最终执行windowAll()的节点会获得大量的入站网络流量以及该节点CPU的显着峰值。这显然是因为所有数据都聚合在一起,并行性为“1”。

Flink中是否有任何当前或计划的条款可以执行更多的双层汇总聚合,以保留每个节点上的所有数据,在将结果发送到第二层以进行最终聚合之前预先聚合它?这是我希望找到的一些伪代码:

val myStream = sourceStream
  .keyBy( 0 )    
  .window(TumblingProcessingTimeWindows.of(Time.minutes(5)))          
  .reduce(_ + _)
  .addSink(new OtherSink)

val summaryStream = myStream
  .map(Row.fromOtherRow(_))
                     // parallelism would be at the default for the env
  .windowLocal(TumblingProcessingTimeWindows.of(Time.minutes(5)))
  .reduce(_ + _)
                     // parallelism is 1 by definition
  .windowAll(TumblingProcessingTimeWindows.of(Time.minutes(5)))
  .reduce(_ + _)
  .addSink(new RowSink)

我称之为'windowLocal()',但我相信可能有一个更好的名字。它就像windowAll()一样是非键控的。关键的好处是它可以减少网络和CPU和内存命中windowAll(),通过在您运行的所有节点上分配它。我目前必须为节点分配更多资源以适应此摘要。

如果可以通过当前版本以其他方式实现,我很乐意听到它。我已经考虑过为第二层的密钥使用随机值,但我相信这会导致数据的完全重新平衡,因此它解决了我的CPU和内存问题,而不是网络问题。我正在寻找与rescale()相同的东西,其中数据保持在任务管理器或插槽的本地。

1 个答案:

答案 0 :(得分:0)

使用FoldFunction进行增量窗口聚合

以下示例显示了如何将增量FoldFunction与WindowFunction结合以提取窗口中的事件数,并返回窗口的键和结束时间。

val input: DataStream[SensorReading] = ...

input
 .keyBy(<key selector>)
 .timeWindow(<window assigner>)
 .fold (
    ("", 0L, 0),
    (acc: (String, Long, Int), r: SensorReading) => { ("", 0L, acc._3 + 1) },
    ( key: String,
      window: TimeWindow,
      counts: Iterable[(String, Long, Int)],
      out: Collector[(String, Long, Int)] ) =>
      {
        val count = counts.iterator.next()
        out.collect((key, window.getEnd, count._3))
      }
  )

使用ReduceFunction进行增量窗口聚合

以下示例显示了如何将增量ReduceFunction与WindowFunction结合使用,以返回窗口中的最小事件以及窗口的开始时间。

val input: DataStream[SensorReading] = ...

input
  .keyBy(<key selector>)
  .timeWindow(<window assigner>)
  .reduce(
    (r1: SensorReading, r2: SensorReading) => { if (r1.value > r2.value) r2 else r1 },
    ( key: String,
      window: TimeWindow,
      minReadings: Iterable[SensorReading],
      out: Collector[(Long, SensorReading)] ) =>
      {
        val min = minReadings.iterator.next()
        out.collect((window.getStart, min))
      }
  )

你想要更多看到这里 enter code here https://ci.apache.org/projects/flink/flink-docs-release-1.2/dev/windows.html