2012-02-12 59 views
13

我在决定使用python multiprocessing或芹菜或pp为我的应用程序时有点麻烦。我的应用程序是非常重的CPU,但目前只使用一个CPU,所以我需要将它传播到所有可用的CPU(这导致我看看Python的多处理库),但我读了这个库不能缩放到其他机器如果需要。现在我不确定是否需要多个服务器来运行我的代码,但我想在本地运行celery,然后扩展只需要添加新的服务器而不是重构代码(如果我使用多)。Celery是否像Python多处理一样在本地系统上高效?

我的问题:这个逻辑正确吗?并且在本地使用芹菜时是否会有任何负面(性能)(如果事实证明一台具有多个核心的服务器可以完成我的任务)?还是建议使用多处理,并在以后增加其他功能?

谢谢!

p.s.这是一个个人学习项目,但我可能有一天喜欢在一家公司工作,想要学习专业人员如何做。

+0

是什么让你认为多个CPU可以帮助IO应用程序?如果您的应用程序是IO绑定的,那么您需要多个IO通道,而不是CPU。 – 2012-02-12 16:46:52

+0

对不起错误的单词......这是非常CPU密集型。基本上它只是一个大数据输入的大型递归数学。看起来像一个好的过程分发 – Lostsoul 2012-02-12 17:01:30

+0

啊 - 在这种情况下,继续:)你需要容错 - 例如,试图使用分散在各地的志愿者计算 - 或者你只是想在实验室或一个实验室使用计算机簇? – 2012-02-12 17:47:54

回答

4

我实际上从来没有使用芹菜,但我已经使用多处理。

芹菜似乎有几种方法是传递消息(任务),包括方法,你应该能够在不同的机器上运行的工人。因此,消极传递可能比多处理速度慢,但另一方面,您可以将负载传播到其他机器。

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

我不知道Celery如何处理任务失败。例如,任务可能永远不会结束运行,或者可能会崩溃,或者如果任务没有在某个时间限制内完成,您可能希望具有终止任务的能力。如果不存在,我不知道如何增加对此的支持。

多不来与容错开箱即用,但你可以建立自己没有太多的麻烦。

+2

由于消息传递的开销,Celery确实比使用multiprocessing.Pool有更多的开销。 Celery以任何形式处理任务失败,它也支持时间限制以及更多。 Celery使用多处理池(celery.concurrency.processes.pool.Pool)的改进版本,该版本支持时间限制并修复与将Pool作为服务运行(即永久运行)相关的许多错误以及与关闭相关的错误。有些人使用芹菜的游泳池版本。 – asksol 2012-02-12 09:38:49

+0

部分链接:http://docs.celeryproject.org/zh/latest/userguide/workers.html#time-limits http://docs.celeryproject.org/en/latest/userguide/workers.html#revoking-tasks池选项:http://docs.celeryproject.org/en/latest/internals/reference/celery.concurrency.processes.pool.html#celery.concurrency.processes.pool.Pool http://docs.celeryproject.org/ en/latest/internals/reference/celery.concurrency.processes.pool.html#celery.concurrency.processes.pool.Pool.apply_async – asksol 2012-02-12 09:44:00

+2

您也可以使用多重处理跨机器分发工作,但我不会推荐这样做。制作高质量的产品可能需要付出相当大的努力,而且芹菜已经有一个解决这些问题的社区。 – asksol 2012-02-12 09:47:25

17

我完成了一个测试,以决定多少芹菜为增加开销超过multiprocessing.Pool和共享阵列。测试在(292,353,1652)uint16阵列上运行维纳滤波器。两个版本都使用相同的组块(大致:将292,353尺寸除以可用CPU数量的平方根)。尝试了两种芹菜版本:一种解决方案发送腌制数据,另一种解决方案打开每个工人的底层数据文件。

结果:在我的16核i7 CPU芹菜约需16S,multiprocessing.Pool用约15秒共享阵列。我发现这种差异惊人的小。

增加粒度增加的差明显(芹菜必须通过多个消息):芹菜需要15秒,multiprocessing.Pool需要12S。

要考虑到芹菜工人已经在主机上运行,​​而池工人在每次运行分叉。我不知道我怎么会从头开始多处理池,因为我将共享阵列的初始化:

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

,只有resarrays被锁定保护。

+1

我设法从测量中分离池设置,但几乎没有区别(如预期的那样,叉子便宜)。 尝试使用其他数据集(276,385,3821):芹菜通过酸洗转移38s,多处理。池27s。 老实说,我发现芹菜更舒适的工作,它可以自然委托处理其他机器的情况下处理时间是真正长于转移时间。在单台机器上,只有大型数据集才能显着提高性能。 – 2013-04-08 16:13:58

相关问题