首页 > 解决方案 > GAE 任务推送失败

问题描述

我正在使用 GAE 任务队列来更新 Datastore 中的批量数据。记录数约为1-2M。为此,我以这种方式安排了一个 cron 作业和一个队列

<queue>
    <name>queueName</name>
    <rate>20/s</rate>
    <bucket-size>300</bucket-size>
    <retry-parameters>
        <task-retry-limit>1</task-retry-limit>
    </retry-parameters>
    <max-concurrent-requests>800</max-concurrent-requests>
</queue>

每个任务都在执行以下任务

  1. 使用游标从数据存储中获取 1500 条记录。
  2. 如果存在下一个游标,则创建一个新任务并推入队列。
  3. 进程 1500 获取记录,意味着更新数据存储中的所有 1500。

添加的预期任务应该在 667 左右,但我只能在日志中看到 40 个任务。

在日志中,我可以看到在 40 秒内将 40 个任务添加到队列中。我在日志中没有收到任何错误。

任何人都可以帮助我了解正在发生的事情吗?为什么我无法添加所有任务。

谢谢

标签: javagoogle-app-enginetask-queue

解决方案


在您的方法中,任务入队似乎与任务请求处理非常紧密地耦合在一起,因为需要处理对队列中一个此类任务的请求才能将下一个任务入队。因此,您需要查看您可能遇到的任务处理速率限制因素。您的队列配置中的那些非常慷慨,但还有其他的。

如果您配置了您的应用程序,threadsafe并且您的应用程序设计利用了它,您的应用程序实例将能够同时处理多个请求,最多取决于其max-concurrent-requests配置处理延迟。没有threadsafe最大为 1 的配置。

一旦一个实例达到它可以同时处理的最大任务请求数,它就不会开始处理队列中的新任务(因此它不会执行步骤#1 - 将新任务入队),直到它完成处理至少一个已经在进行的任务。因此,每个应用程序实例的任务入队率受到了有效限制——每个正在运行的实例只能对队列中的任务总数做出贡献,其数量等于它可以并行处理的最大任务数。

但是您的应用程序已配置为自动扩展,因此一旦您设法快速“填满”所有正在运行的实例,调度程序将为它启动新实例。随着新实例的启动,它们将能够处理队列中的更多任务,从而也将新任务排入队列,从而为队列中的任务总数贡献上述数量。

但是,排队任务数量的增长可能比实例没有达到其最大处理速率时要慢得多 - 需要一些时间来衡量新实例如何帮助流量以确定是否需要更多实例。队列中任务数量的总体增长将具有“阶梯式”曲线,步骤的高度是实例可以处理的最大并发请求数,步骤数是启动的新实例数 +1 .

由于您没有看到任何实际的任务排队错误,我只能怀疑您在处理排队任务时以某种方式达到了速率限制,或者以某种方式完全停止了处理。可能有很多原因,例如:

  • 达到应用的每日预算(很可能是由于实例小时数)
  • 达到自动缩放限制

您必须从这个角度调查您的应用程序以查明罪魁祸首。

旁注:我假设这是在 GAE 上,而不是在开发服务器上(它不尊重任务队列配置,很可能甚至无法接近 GAE 的并行处理能力)。


推荐阅读