我正在进行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个输出。
答案 0 :(得分:0)
我想我已经理解了这一点。
滑动窗口使用.every()函数创建一个新窗口。设置早期点火适用于每个窗口,因此获得多次点火是有道理的。
为了适应我的用例并只输出&#34;当前窗口&#34;,我在输出结果和调整.every之前检查c.pane()。isFirst()== true ()控制频率。