在 PubSub 订阅确认截止日期和重新传递的上下文中,未发送给订阅者的消息是啥意思?

Posted

技术标签:

【中文标题】在 PubSub 订阅确认截止日期和重新传递的上下文中,未发送给订阅者的消息是啥意思?【英文标题】:What is the meaning of messages outstanding to a subscriber in the context of PubSub subscription acknowledge deadlines and re-delivery?在 PubSub 订阅确认截止日期和重新传递的上下文中,未发送给订阅者的消息是什么意思? 【发布时间】:2020-10-18 01:20:47 【问题描述】:

我们以“尖峰”方式使用 Google PubSub,我们在短时间内(约 10 分钟)发布数百万条小消息( 我们注意到,随着这些积压工作的大小从 100 万增加到 1000 万,在某些小时内从低于 1% 到超过 10%,我们注意到重新传递的消息有所增加。

来自 GAE 任务拉取队列世界,我们假设工作人员会通过从 PubSub 订阅中拉取消息来“租用”消息,其中从拉取时开始,工作人员将有 10 分钟的时间来确认消息. 然而,在添加日志记录之后(参见下面重新发布消息的示例),似乎发生的事情不是从拉取到确认的时间,而是从发布消息到确认的时间。

这是对 PubSub 确认截止日期以及随后的重新交付行为的正确理解吗?

如果是这样,我们是否应该确保订阅的消息积压仅增长到工作线程能够在为订阅的确认截止日期配置的时间内处理和确认的大小,以使重新传递率低于 0.1%平均的? 尽管 GAE 拉取任务队列租赁行为似乎更直观,但我们可能可以让发布者根据订阅积压大小应用某种背压。

此外,https://cloud.google.com/pubsub/docs/subscriber#push-subscription 中的“Pull subscription”下的措辞:“订阅应用程序显式调用 pull 方法,它请求传递消息”似乎暗示确认超时在客户端 pull 调用返回给定的留言?

注意:我们使用 Python PubSub API (google-cloud-pubsub),但不是默认的流式传输行为,因为这会导致 PubSub 文档中描述的“消息囤积”,因为我们发布了大量的小消息。相反,我们调用subscriber_client.pull 并确认(这似乎是围绕PubSub 服务API 调用的薄包装)

PullMessage.ack: 1303776574755856 delay from lease: 0:00:35.032463 (35.032463 seconds), publish: 0:10:02.806571 (602.806571 seconds)

【问题讨论】:

【参考方案1】:

确认截止日期是从 Cloud Pub/Sub 向订阅者发送消息到收到对该消息的确认调用之间的时间。 (这不是发布消息和确认消息之间的时间。)通过原始同步拉取和确认调用,订阅者负责管理租约。这意味着如果没有显式调用modifyAckDeadline,则必须在确认截止日期(默认为10 seconds,而不是10 分钟)之前确认消息。

如果您使用 Cloud Pub/Sub 客户端库之一,收到的消息将自动延长其租期。此租约管理工作方式的行为取决于库。例如,在 Python 客户端库中,租约会根据先前消息的确认时间进行扩展。

邮件重新投递的原因有很多。随着积压的增加,工作人员的负载可能会增加,从而增加工作人员的排队时间以及确认消息所花费的时间。您可以尝试增加您的工作人员数量,看看这是否会提高您对大量积压的重新交付率。此外,消息被确认的时间越长,它们被重新传递的可能性就越大。服务器可能会忘记它们并再次发送它们。

您可以在发布方面做一件事来减少消息重新传递 - 减少您的发布批量大小。在内部,确认状态是按批次存储的。因此,即使批次中的一条消息超过了 ackDeadline,它们都可能会被重新发送。

消息重新传递可能由于许多其他原因而发生,但扩展您的工作人员可能是一个不错的起点。您也可以尝试减少发布批量大小。

【讨论】:

感谢普拉德澄清。听起来应该可以建立数百万订阅积压(如图所示),只要工作人员在配置的确认期限内拉/确认消息。我们将订阅确认截止日期设置为 10 分钟,并添加了统计信息来跟踪我们提取一组消息和调用确认 PubSub API 之间的时间,似乎我们保持在 10 分钟阈值以下。我们会使用高达 10MB 的负载对发布 API 调用进行批处理,因此我们将调查这些调用的大小并寻找减少这些批处理的方法。 是的,建立大量积压应该没问题。更长的确认截止日期和消息量的组合可能意味着更多的重新传递,这只是因为我们必须保留多少状态。由于各种内部原因,其中一些可能会被丢弃,从而导致重新交付。为了澄清,“发布批量大小的大小”是指消息的数量,而不是字节。如果您的消息只有 5 KB,那么每 10 MB 批次发布的消息要比 1 MB 多得多。

以上是关于在 PubSub 订阅确认截止日期和重新传递的上下文中,未发送给订阅者的消息是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

Google Cloud PubSub 不确认消息

PubSub 不确认消息

pubsub 流式处理 pull nack 与无确认行为

如何修改后台 Cloud Function 的 Google Cloud Pub/Sub 订阅确认截止日期

PubSub 最大传递尝试次数和死信主题

GCP 中的确认截止日期、消息保留时间、死信和重试策略