【问题标题】:Best way for running long Python scripts on GCP在 GCP 上运行长 Python 脚本的最佳方式
【发布时间】:2022-01-21 19:42:07
【问题描述】:

我们正在公司开始一个新项目,我们基本上每天两次为每个客户运行几个 Python 脚本。 因此,我们的想法是,每天两次触发 Cloud Function,该函数将为每个客户端触发 Python 脚本,创建 App Engine / Cloud Run 或 Google 提供的任何其他无服务器服务的新实例。

一开始我们想使用 Cloud Functions,但很快我们发现它们不适合长时间运行的 Python 脚本,这些脚本最终会为每个客户端计算和收集不同的信息并将它们写入 Firebase。

流程将是:Cloud Function 触发 -> 每个客户端的函数触发 GCP 实例 -> 为每个客户端运行的脚本 -> 输出被保存到 Firebase。

在没有专用服务器的情况下,推荐哪种方法最适合 GCP 无服务器服务?

【问题讨论】:

  • 您是否为每个客户端并行运行脚本?每个客户端的每个脚本需要多长时间?
  • 嘿@guillaumeblaquiere,每个客户端的每个脚本的持续时间约为 15 分钟,我们正在为每个客户端运行一个脚本,因此每个客户端都有自己的 15 分钟脚本实例

标签: google-app-engine google-cloud-platform google-cloud-functions


【解决方案1】:

有很多很棒的答案!这里的关键是解耦和分发处理。

当您谈论解耦时,您可以使用 Cloud Task(您可以在其中添加具有速率限制的流控制或在将来推迟任务)或 PubSub(更简单的消息队列解决方案)。

并且 Cloud Run 要求运行长达 15 分钟的处理时间。但是您必须对其进行微调(请参阅下面的提示)

所以,总结一下过程

  • 您必须每天触发两次 Cloud Functions。为此,您可以使用 Cloud Scheduler。
  • 触发的 Cloud Functions 获取客户端列表(在数据库中?)并为每个客户端在 Cloud Task 上创建一个任务(或在 PubSub 中创建一条消息)
  • 每个任务(或消息)调用 Cloud Run 上的一个 HTTP 端点,该端点为每个客户端执行该过程。在 Cloud Run 上将超时设置为 30 分钟。

但是,如果您的处理是计算密集型的,则您必须调整 Cloud Run。如果 1vCPU 上 1 个客户端的处理需要 15 分钟,这意味着如果您不想达到超时,则每个 CPU 不能处理超过 1 个客户端(2 个客户端可能会导致您在相同的 CPU,您可以达到超时)。为此,我建议您将 Cloud Run 的并发参数设置为 1,一次只处理一个请求(当然,如果您在 Cloud Run 上设置了 2 或 4 个 CPU,您也可以将并发参数设置为 2 或 4允许在同一实例上进行并行处理,但在不同的 CPU 上)。

如果处理不是 CPU 密集型的(您执行 API 调用并等待答案),则很难说。尝试使用 5、10、30 的并发...并观察已处理请求的行为/延迟。不用担心,使用 Cloud Task 和 PubSUb,您可以设置超时重试策略。

最后一件事:你的处理是幂等的吗?我的意思是,如果您为同一个客户端运行 2 次相同的进程,结果是正确的还是有问题?尝试使解决方案具有幂等性,以克服分布式计算(包括重放)上可能发生的重试问题和全局问题

【讨论】:

  • 非常感谢您的详细回答,我认为这几乎涵盖了所有内容。至于您的问题,如果任务将运行两次没有问题,因为结果只会更正已插入数据库中的那些。此外,该任务不是 CPU 密集型,而是“API 密集型”,因此基本上是在等待来自不同来源的答案。
【解决方案2】:

@NoCommandLine 的回答是最好的建议,如果您想设置更长的运行时间,Cloud Run 也是一个不错的选择,因为超时可以设置在 5 分钟(默认)和 60 分钟之间。您可以通过Cloud Console, command line or YAML 设置或更新请求超时。

同时,Cloud Function 的执行时间只有 1 分钟(默认),最长可设置为 9 分钟。

您可以查看以下完整文档:

你也可以通过这个link查看相关的SO问题。

【讨论】:

  • 感谢您的回答,我们发现 Cloud Run 可以满足我们的大部分要求,此时我们将在 GAE 和 Cloud Run 中设置脚本,以便我们可以比较它们,希望我将在这里分享我的答案。
  • 请注意,即使 Cloud Run 接受更长的超时时间,Cloud Task 也会有 30 分钟的超时时间。但这已经足够了。
【解决方案3】:

您可以使用Cloud Tasks 执行“长时间”运行的 Google App Engine (GAE) 任务。

多长时间(这就是我用引号引起来的原因)取决于您用于 GAE 项目实例的扩展类型。设置为“自动扩展”的实例最长为 10 分钟,而设置为“手动”或“基本”的实例最长为 24 小时。

来自之前的链接

....所有工作人员必须向云端发送 HTTP 响应代码 (200-299) 任务服务,在这种情况下,在截止日期之前基于 服务实例伸缩类型:自动伸缩10分钟 或长达 24 小时进行手动缩放。如果发送不同的响应, 或者没有响应,任务重试......

添加更新(30 分钟与 24 小时之间似乎有些混淆)

标准 HTTP 请求的最长执行时间为 30 分钟 (source),而如果您使用手动缩放 (source),GAE 端点可以运行长达 24 小时

【讨论】:

  • 据我了解(我可能完全错了)Cloud Run 将实现完全相同的效果,不是吗?万一它为什么要使用另一个呢?
  • 也许吧。我对 Cloud Run 不像对 GAE 那样熟悉(我们为 GAE 构建了一个应用程序)。如果您可以使用 Cloud Run 实现相同的目标,那就去做吧。如果 Cloud Run 执行长时间运行的任务,它最终可能会比 GAE 便宜,因为 GAE 需要手动扩展超过 10 分钟的任何时间,这意味着实例在不处理任何请求时不会降到 0。当 Cloud Run 不为任何请求提供服务时,它会变为 0。
  • 另外,如果我理解正确,Cloud Tasks 的最大超时时间为 30 分钟,这意味着如果我长时间运行的 GAE 任务无法在这 30 分钟内完成,Cloud Task 将退出该任务并重新运行它,不是吗?
  • 没有。 30 分钟用于“标准”HTTP 请求。带有 App Engine 端点的请求最多可以运行 24 小时 - cloud.google.com/tasks/docs/dual-overview#appe 更新了我的答案以提供来源
猜你喜欢
  • 2020-10-24
  • 2019-09-24
  • 1970-01-01
  • 2014-10-27
  • 1970-01-01
  • 2018-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多