【发布时间】:2019-09-24 08:58:05
【问题描述】:
我有一个芹菜任务:
@app.task(bind=True, soft_time_limit=FreeSWITCHConstants.EXECUTE_ATTEMPTS_LOCAL_SOFT_TIME_LIMIT)
def execute_attempt_local(self, attempt_id, provider_id, **kwargs):
print "PERF - entering execute_attempt_local"
...
由具有以下配置的(远程)工作人员处理:
celery -A mycompany.web.taskapp worker n -Q execute_attempts-2 --autoscale=4,60
此任务一次生成数千个,历来在 1-3 秒内完成(它主要是 I/O 绑定任务)。
最近随着我们应用程序的整体使用量增加,此任务的完成时间平均增加到 5-8 秒,我试图了解是什么占用了额外的时间。我注意到对于需要 5-8 秒的许多任务,从线程接受任务到执行任务的第一行之间的时间大约需要 4 秒:
[2019-09-24 13:15:16,627: DEBUG/MainProcess] Task accepted: mycompany.ivr.freeswitch.tasks.execute_attempt_local[d7585570-e0c9-4bbf-b3b1-63c8c5cd88cc] pid:7086
...
[2019-09-24 13:15:22,180: WARNING/ForkPoolWorker-60] PERF - entering execute_attempt_local
在那个 4s 中发生了什么?我假设我有一个 Celery 配置问题,并且在某个地方缺乏资源来让这些任务更快地处理。有什么想法可能会减慢他们的速度吗?
【问题讨论】:
-
它甚至可能是几分钟,甚至几个小时 - 取决于您的工人的利用率,对吧。如果你发送了 10000 个任务,而你只有 10 个可用的工作进程,谁知道其他 9990 个任务什么时候开始......
-
我认为你的意思是线程,而不是工人,对吧?如果是这样,您是说 celery 在这里等待移交给线程,因为没有线程可用?这意味着如果我增加自动缩放,我应该在这里看到改进吗?
-
你使用 prefork 并发,所以这些都是简单的过程。我们的集群也使用它,我们每天运行多达 500 万个任务......
-
Autoscaling 是,不管你信不信,Celery 的弃用功能,因为没有人有兴趣维护它。所以我建议你修复并发
N * <number of cores>,因为你的任务是 IO 绑定的,所以你可以拥有比核心数量多 2-3 倍的工作进程。
标签: python django performance celery django-celery