计算流管道中的不同值

时间:2017-02-14 01:49:37

标签: google-cloud-dataflow dataflow

我有一个看起来像

的管道
pipeline.apply(PubsubIO.read.subscription("some subscription"))
            .apply(Window.into(SlidingWindow.of(10 mins).every(20 seconds)
                            .triggering(AfterProcessingTime.pastFirstElementInPane()
                    .plusDelayOf(20 seconds))
                    .withAllowedLateness(Duration.ZERO)
                    .accumulatingFiredPanes()))
            .apply(RemoveDuplicates.create())
            .apply(Window.discardingFiredPanes()) // this is suggested in the warnings under https://cloud.google.com/dataflow/model/triggers#window-accumulation-modes
            .apply(Count.<String>globally().withoutDefaults())

此管道显着地超过了不同的值(20倍正常值)。最初,我怀疑默认触发器可能导致了这个问题。我已经调整使用触发器,它不允许延迟/丢弃触发窗格/使用处理时间,所有这些都有类似的过度计数问题。

我也试过ApproximateUnique.globally:它在管道构建期间失败了,因为看起来像是异常 Default values are not supported in Combine.globally() if the output PCollection is not windowed by GlobalWindows.似乎无法向其添加withoutDefaults(就像我们对Count.globally所做的那样)。

是否建议以合理的精度在数据流/波束流管道中执行COUNT(DISTINCT)

P.S。我正在使用Java Dataflow SDK 1.9.0。

1 个答案:

答案 0 :(得分:2)

您的代码看起来不错;它不应该超额计算。请注意,您将每个元素放置在30个窗口中,因此如果您有一个不知道窗口的接收器(相当于折叠所有滑动窗口),那么您可以期望精确到30倍的元素。如果您可以显示更多的管道或如何观察计数,那可能会有所帮助。

除此之外,我对管道提出了一些建议:

  • 我建议您将RemoveDuplicates的触发器更改为AfterPane.elementCountAtLeast(1);这将在较低的延迟时间内获得相同的结果,因为后来的元素到达将没有任何影响。此触发器和您当前的触发器将永远不会重复触发。因此,无论您设置accumulatingFiredPanes()还是discardingFiredPanes(),实际上并不重要。这很好,因为没有人可以使用你的其他管道。
  • 我会在Count之前安装新触发器。原因有点技术性,但我会尝试描述它:
    • 在当前的管道中,安装在那里的触发器(RemoveDuplicates的触发器的“延续触发器”)记录第一个元素的到达时间,并等待它收到在或之前生成的所有元素处理时间,由上游工作人员测量。有一些不确定性,因为它会影响当地的处理时间和其他工人的处理时间。
    • 如果您接受我的建议并切换RemoveDuplicates的触发器,则继续触发器将为AfterPane.elementCountAtLeast(1),因此它将始终尽快发出计数,然后丢弃更多数据,这非常错。