对于在GCD上运行的PubsubIO,水印启发式是什么?

时间:2017-02-10 21:33:01

标签: google-cloud-dataflow

嗨我正在尝试运行一个管道,我正在计算发布到pubsub的消息与30秒心跳*(10K流,每个心跳每30秒)之间的差异。我不关心100%的数据完整性,但我想了解PubsubIO的水印启发式(以及我是否可以调整它),以确定我是否能够以足够低的损失忽略后期数据。

*注意,pubsub主题提供了[可能有几天]持久性,以防我们必须关闭管道,因此启发式工作与积压订阅很有效。

有人可以解释如何计算水印(假设使用了timestamplabel()),以及如何调整它(如果有的话)?

1 个答案:

答案 0 :(得分:18)

以下是我们如何计算PubSub水印的简要说明:

我们的目标是为通过PubSub发送到流媒体管道的数据构建合理的启发式水印。我们对将数据发送到PubSub的源进行了一些假设。具体来说,我们假设原始数据的时间戳“表现良好”,换句话说,在将数据发送到PubSub之前,我们期望源数据上有限量的我们的订单时间戳。使用超出允许的无序边界的时间戳发送的任何数据都将被视为延迟数据。在我们当前的实现中,此绑定 10秒意味着在发送到pubsub之前重新排序时间戳最多10秒将不会创建延迟数据。我们将此值称为估算带。建立PubSub水印的问题然后减少到确保没有其他数据由于通过PubSub传输而迟到。

PubSub面临的挑战是什么?由于pubsub不保证订购,我们必须有一些额外的元数据来充分了解积压。幸运的是,PubSub根据“最早的未打包发布时间戳”提供了对日志的测量。这与我们的消息的事件时间戳不同,因为PubSub与通过它发送的应用程序级元数据无关,而这是PubSub提取消息的时间戳。

虽然此测量听起来类似于水印,但它不一样。我们不能简单地使用最旧的未打包发布时间戳作为水印。这些时间戳不等于事件时间戳,并且在发送历史(过去)数据的情况下,它可以任意地远离。这些时间戳的排序也可能不同,因为如上所述,我们允许有限的重新排序。但是,我们可以使用它来衡量积压,以便了解有关积压中存在的事件时间戳的足够信息,以便我们可以建立合理的水印,如下所示。

我们将订阅的数据称为基本订阅。看一下我们的基本订阅,我们发现消息可能无序到达。我们使用pubsub发布时间戳“pt”及其事件时间时间戳“et”标记每条消息。请注意,这两个时域可以不相关

Base subscription timestamps

基本订阅上的某些消息未得到确认,形成了积压。这可能是由于它们尚未交付,或者它们可能已经交付但尚未处理。还要记住,此订阅的提取分布在多个分片中。因此,不可能仅仅通过查看基本订阅来说明我们的水印应该是什么。

我们继续创建第二个仅元数据跟踪订阅,用于有效检查基本订阅的积压,并在积压中记录最少的事件时间戳。通过在跟踪订阅上保持很少或没有积压,我们可以检查基本子目录最旧的未通过之前的消息。

enter image description here

我们始终关注跟踪订阅,确保从此订阅中获取的计算成本低廉。相反,如果我们落后跟踪订阅,我们将停止推进水印。为此,我们确保满足以下至少一个条件:

  • 跟踪订阅充分领先于基本订阅,充分领先意味着跟踪订阅至少提前估计带。这可确保考虑估计范围内的任何有界重新排序。
  • 跟踪订阅足够接近实时。换句话说,跟踪订阅没有积压。

一旦我们持久地保留了有关消息的发布和事件时间戳的元数据,我们就会尽快确认跟踪订阅上的消息。我们以稀疏的直方图格式存储这些元数据,以最大限度地减少使用的空间量和持久写入的大小。

最后,我们确保我们有足够的数据来进行合理的水印估算。我们采用一系列事件时间戳,其中包含

范围内的发布时间戳
 [ min ( base sub oldest unack'd, tracking sub oldest unack'd - 10 sec) , 
         tracking sub oldest unack'd ]

这可以确保我们考虑积压中的所有事件时间戳,或者如果积压很小(最近的估算带),则进行水印估算。

最后,水印值被计算为频带中的最小事件时间。

另请注意,此方法是正确的,但会产生过于保守的水印。由于我们认为跟踪订阅中基本订阅之前的所有消息都是最旧的,因此我们可能会在已经确认的消息的水印估计中包含事件时间戳。

此外,还有一些启发式方法可以确保取得进展。在密集,频繁到达的数据的情况下,上述方法很有效。在稀疏或不频繁的数据的情况下,可能没有足够的最近消息来建立合理的估计。如果我们还没有看到超过两分钟的订阅数据(并且没有积压),我们会将水印提前接近实时。这确保即使没有更多消息即将出现,水印和管道仍继续取得进展。

以上所有内容确保只要源数据事件时间戳重新排序在估计范围内,就不会有额外的延迟数据。