Celery任务调用子进程时的CPU并发行为

2 投票
1 回答
1934 浏览
提问于 2025-04-18 05:54

我有一个celery任务,它使用subprocess.Popen()来调用一个可执行文件,这个文件进行一些需要大量计算的数据处理。这个方法运行得不错,但没有充分利用celery工作进程的并发能力。

当我用--concurrency 8 -P prefork启动celeryd时,我可以通过ps aux | grep celeryd确认已经生成了8个子进程。好的。

现在,当我同时启动例如3个任务时,我发现这三个任务都被一个子工作进程接收了:

[2014-05-08 13:41:23,839: WARNING/Worker-2] running task a... [2014-05-08 13:41:23,839: WARNING/Worker-4] running task b... [2014-05-08 13:41:24,661: WARNING/Worker-7] running task c...

...它们运行了几分钟才成功完成。然而,当你观察这段时间的CPU使用情况时,很明显这三个任务都在共享同一个CPU,尽管还有其他空闲的核心:

enter image description here

如果我再添加两个任务,每个子进程大约占用那一个CPU的20%左右,等等。

我本以为每个子celery进程(通过prefork方法使用multiprocessing.Pool创建)应该能够独立运行,而不受限于单个核心。如果不是的话,我该如何充分利用多个CPU核心来处理这个需要大量计算的celery任务呢?

1 个回答

2

根据

http://bugs.python.org/issue17038https://stackoverflow.com/a/15641148/519385

有一个问题是,一些C语言的扩展会干扰核心亲和性,导致多进程无法使用所有可用的CPU。解决这个问题的方法虽然有点黑科技,但似乎有效。

os.system("taskset -p 0xff %d" % os.getpid())

撰写回答