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

What is the meaning of messages outstanding to a subscriber in the context of PubSub subscription acknowledge deadlines and re-delivery?

我们以 'spiky' 的方式使用 Google PubSub,我们在短时间内(约 10 分钟)发布数百万条小消息(< 10k),启动 2k GKE pods 有 10 个工作线程,每个工作线程使用同步拉取和确认 PubSub 服务调用来完成相关订阅(确认截止时间为 10 分钟)。 订阅积压的 Stack Driver 图将显示 10M 消息的峰值,然后在大约 30 分钟内下降到 0(见下文)。
我们注意到,随着这些积压的大小从 1M 增加到 10M,在某些时间段内从低于 1% 增加到超过 10%,我们注意到消息重新传递有所增加。

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

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

如果是这样,我们是否应该确保订阅的消息积压只增长到工作线程能够在为订阅的确认截止日期配置的时间内处理和确认的大小,以使重新传送率小于 0.1 % 一般? 尽管 GAE Pull Task Queue 租赁行为看起来更直观,但我们或许可以让发布者根据订阅积压大小应用某种背压。

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

注意:我们使用 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)

确认截止时间是云 Pub/Sub 向订阅者发送消息和收到对该消息的确认调用之间的时间。 (这不是发布消息和确认消息之间的时间。)使用原始同步拉取和确认调用,订阅者负责管理租约。这意味着没有显式调用 modifyAckDeadline, the message must be acked by the ack deadline (which defaults to 10 seconds,而不是 10 分钟)。

如果您使用云 Pub/Sub 客户端库之一,收到的消息将自动延长租期。这种租用管理的工作方式取决于图书馆。例如,在 Python 客户端库中,租约根据之前消息的确认时间延长。

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

您可以在发布端做一件事来减少消息的重新投递 - 减少您的发布批量大小。在内部,ack 状态是按批存储的。因此,即使一批消息中的一条消息超过了 ackDeadline,它们也可能全部重新传送。

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