Celery 在本地系统上的效率与 python 多处理一样吗?

Posted

技术标签:

【中文标题】Celery 在本地系统上的效率与 python 多处理一样吗?【英文标题】:Is Celery as efficient on a local system as python multiprocessing is? 【发布时间】:2012-03-03 23:27:33 【问题描述】:

我在决定为我的应用程序使用 python 多处理或 celery 或 pp 时遇到了一些麻烦。

我的应用程序 CPU 很重,但目前只使用一个 cpu,所以我需要将它分布在所有可用的 cpu 上(这导致我查看 python 的多处理库)但我读到这个库不能扩展到其他机器如果需要的话。现在我不确定是否需要不止一台服务器来运行我的代码,但我正在考虑在本地运行 celery,然后扩展只需要添加新服务器而不是重构代码(就像我使用多处理)。

我的问题:这个逻辑正确吗?并且在本地使用芹菜是否有任何负面(性能)(如果事实证明具有多个内核的单个服务器可以完成我的任务)?还是更建议使用多处理并在以后将其发展成其他东西?

谢谢!

附言这是一个个人学习项目,但我也许有一天想在一家公司担任开发人员并想了解专业人士是如何做到的。

【问题讨论】:

是什么让您认为多个 CPU 将有助于 IO 密集型应用程序?如果您的应用程序是 IO 密集型的,那么您需要多个 IO 通道,而不是 CPU。 对面对不起错词...它非常占用 CPU。基本上它只是具有大量数据输入的大型递归中的数学。似乎是一个很好的分发过程 啊 - 在这种情况下,继续 :) 您是否需要容错 - 例如,尝试使用分散在各处的志愿计算 - 或者您只是想在实验室或实验室中使用计算机集群? 亲爱的 lostsoul,请更新问题:它是 cpu 密集型的,而不是 IO。 【参考方案1】:

我刚刚完成了一项测试,以确定 celery 在 multiprocessing.Pool 和共享数组上增加了多少开销。该测试在 (292, 353, 1652) uint16 数组上运行 wiener 滤波器。两个版本都使用相同的分块(大致:将 292,353 个维度除以可用 CPU 数量的平方根)。尝试了两种 celery 版本:一种解决方案发送腌制数据,另一种解决方案在每个工作人员中打开底层数据文件。

结果:在我的 16 核 i7 CPU 上,celery 大约需要 16 秒,multiprocessing.Pool 共享阵列大约需要 15 秒。我发现这种差异非常小。

增加粒度明显增加差异(celery 必须传递更多消息):celery 需要 15 秒,multiprocessing.Pool 需要 12 秒。

考虑到 celery 工作人员已经在主机上运行,​​而池工作人员在每次运行时都会分叉。我不确定如何从一开始就启动多处理池,因为我在初始化程序中传递了共享数组:

with closing(Pool(processes=mp.cpu_count(), initializer=poolinit_gen, initargs=(sourcearrays, resarrays))) as p:

并且只有 resarrays 受到锁定保护。

【讨论】:

我设法将池设置与测量分开,但这几乎没有什么区别(正如预期的那样,fork 很便宜)。尝试使用另一个数据集(276、385、3821):celery via pickled transfer 38s,multiprocessing.Pool 27s。老实说,我发现 celery 使用起来更舒服,它可以自然地将处理委托给其他机器,以防处理时间真的比传输时间长。在单台机器上,只有大型数据集的性能差异才会明显。【参考方案2】:

我实际上从未使用过 Celery,但我使用过多处理。

Celery 似乎有几种传递消息(任务)的方式,包括您应该能够在不同机器上运行工作人员的方式。因此,缺点可能是消息传递可能比多处理慢,但另一方面,您可以将负载分散到其他机器。

你说得对,多处理只能在一台机器上运行。但另一方面,进程之间的通信可以非常快,例如通过使用共享内存。此外,如果您需要处理大量数据,您可以轻松地从本地磁盘读写数据,并且只需在进程之间传递文件名。

我不知道 Celery 处理任务失败的能力如何。例如,任务可能永远不会完成运行,或者可能会崩溃,或者如果任务没有在特定时间限制内完成,您可能希望能够终止该任务。如果不存在,我不知道添加对它的支持会有多难。

多处理并没有开箱即用的容错功能,但您可以自己构建它而不会遇到太多麻烦。

【讨论】:

Celery 确实比直接使用 multiprocessing.Pool 有更多的开销,因为消息传递开销。 Celery 可以很好地处理任何形式的任务失败,它还支持时间限制等等。 Celery 使用多处理池(celery.concurrency.processes.pool.Pool)的改进版本,它支持时间限制并修复了许多与将池作为服务运行(即永远运行)相关的错误,以及与关闭相关的错误。有些人使用 Celery 的 pool 版本。 一些链接:docs.celeryproject.org/en/latest/userguide/…docs.celeryproject.org/en/latest/userguide/… 池选项:docs.celeryproject.org/en/latest/internals/reference/…docs.celeryproject.org/en/latest/internals/reference/… 您也可以仅使用多处理在机器之间分配工作,但我不建议这样做。使其达到生产质量可能需要付出相当大的努力,而 Celery 确实已经有一个社区正在解决这些问题。 请记住,在多处理中,共享比多线程慢。因此,仅在 CPU 密集型任务需要时使用。

以上是关于Celery 在本地系统上的效率与 python 多处理一样吗?的主要内容,如果未能解决你的问题,请参考以下文章

python测试开发django-158.celery 学习与使用

永久激活 cpanel 主机上的 celery worker 和 celery beat

解决Django + Celery 长链接问题(一段时间后就断开) #原理待查

Apache Airflow Celery Executor。导入一个本地自定义的python包

php怎么调用celery任务

Python:使用celery处理多个服务器上的参数列表