我正在队列中运行一系列长时间运行的重量级 Celery 任务(生成多个子进程),CELERYD_CONCURRENCY = 4
。最初,4 个任务按预期启动。然而,随着任务完成,直到更多任务完成后才会开始新任务,很快 Celery 会将事件任务的数量减少到 1 或 2,直到所有任务都完成(由 Celery Flower 确认)。
当我只运行简单的任务时,例如默认的 Celery add
函数,一切都按预期工作。
由 Celery 任务启动的子进程(具有与任务相同的进程组 ID)是否计入并发槽?有什么方法可以确保 Celery 只计算任务本身吗?
请您参考如下方法:
Celery 使用 prefork 作为默认执行池,每次生成一个子进程(另一个 fork)时,它都会统计正在运行的并发进程数,即 CELERYD_CONCURRENCY
中的数字。
避免这种情况的方法是使用 eventlet ,这将允许您在每个任务上产生多个异步调用,只要您的任务没有任何阻塞的调用,例如 subprocess.communicate
。
为了进一步优化,您可以尝试将使用 subprocess.communicate 的任务拆分到一个不同的队列中,该队列有一个使用 prefork 的工作线程,而其他所有不会阻塞在使用 eventlet 的工作线程中的任务。