芹菜工人没有填充并发插槽

时间:2014-08-07 16:50:00

标签: python celery celery-task celeryd

我有一个并发为4的工作者。我看到4个进程在花开始,一切看起来都不错。

如果我在shell中执行此操作,那么我会看到4个工作人员执行任务,其余部分保留,并且每次处理4个,直到队列为空。

[my_task.apply_async() for i in xrange(10)]

但是,如果我逐行执行此操作,则只会对前两个任务进行积极处理,从那时起,它一次只处理两个任务。

my_task.apply_async()
my_task.apply_async()
my_task.apply_async()
my_task.apply_async()
...

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

通常这是因为子进程填满了并发槽。 Celery默认使用prefork作为执行池,每次生成一个任务的子进程(另一个fork)时,它都算作一个正在运行的进程来填充并发插槽。

避免这种情况的最简单方法是using eventlet,这将允许您在每个任务上产生多个异步调用。但是,这要求您的任何任务都没有阻塞调用,例如subprocess.communicate,因为它们会阻止所有任务。

否则,如果您有必要的阻止调用,并且您知道您的任务一次只有一个正在运行的子进程,则可以将CELERYD_CONCURRENCY设置为double(8)并设置一个开始任务的时间限制,因此8个任务不会立即开始(例如@app.task(rate_limit='10/m'))。但是,这有点像黑客,使用eventlet绝对是首选。