Apache Beam - 滑动Windows输出多个窗口

时间:2017-12-17 20:10:56

标签: google-cloud-dataflow apache-beam

我正在进行PCollection会话并试图获得每个频道/连接的平均会话持续时间。我做了一些事情,我的早期触发器为每个产生的窗口射击 - 如果每隔1分钟60分钟的窗口滑动,则早期触发器将触发60次。查看输出的时间戳,每分钟都会有一个窗口,持续60分钟。我想在最近的一个窗口触发一次触发器,这样我每10秒钟就会有最后60分钟的平均会话持续时间。

之前我使用了滑动窗口,并且得到了我预期的结果。通过混合滑动和会话窗口,我会以某种方式导致这种情况。

让我给你描绘一下我的管道图片:

首先,我根据活跃用户创建会话:

  .apply("Add Window Sessions", 
Window.<KV<String, String>> into(Sessions.withGapDuration(Duration.standardMinutes(60)))
  .withOnTimeBehavior(Window.OnTimeBehavior.FIRE_ALWAYS)
  .triggering(
   AfterWatermark.pastEndOfWindow()
        .withEarlyFirings(AfterProcessingTime
        .pastFirstElementInPane()
        .plusDelayOf(Duration.standardSeconds(10))))
  .withAllowedLateness(Duration.ZERO)
  .discardingFiredPanes()
 )
 .apply("Group Sessions", Latest.perKey())

此后的步骤创建会话对象,计算会话持续时间等。以PCollection(会话)结束。

我从Pcollection(Session)创建一个KV连接,持续时间。

然后我应用滑动窗口然后应用平均值。

    .apply("Apply Rolling Minute Window",
      Window. < KV < String, Integer >> into(
       SlidingWindows
       .of(Duration.standardMinutes(60))
       .every(Duration.standardMinutes(1)))
      .triggering(
       Repeatedly.forever(
        AfterWatermark.pastEndOfWindow()
        .withEarlyFirings(AfterProcessingTime
         .pastFirstElementInPane()
         .plusDelayOf(Duration.standardSeconds(10)))
       )
      )
      .withAllowedLateness(Duration.standardMinutes(1))
      .discardingFiredPanes()
     )
     .apply("Get Average", Mean.perKey())

此时此刻,我发现了问题。我希望看到的是每个键的单个输出具有平均持续时间。我实际看到的是在接下来的60分钟内每分钟60个输出同一个键。

将此日志记录在DoFn中,其中C为ProcessContext:

LOG.info(c.pane().getTiming() + " " + c.timestamp());

我得到这个输出60次,时间戳是将来60分钟:

EARLY 2017-12-17T20:41:59.999Z
EARLY 2017-12-17T20:43:59.999Z
EARLY 2017-12-17T20:56:59.999Z
(cont)

日志于2017年12月17日19:35:19打印。 输出数量始终是窗口大小/滑动持续时间。所以,如果我每5分钟做60分钟的窗口,我会得到12个输出。

1 个答案:

答案 0 :(得分:0)

我想我已经理解了这一点。

滑动窗口使用.every()函数创建一个新窗口。设置早期点火适用于每个窗口,因此获得多次点火是有道理的。

为了适应我的用例并只输出&#34;当前窗口&#34;,我在输出结果和调整.every之前检查c.pane()。isFirst()== true ()控制频率。