我有一个Django应用程序并使用Celery来处理长时间运行的任务。
假设我需要生成一个文件(需要5秒钟),将其附加到电子邮件中并发送给1000个用户,这些方法中哪一种是首选方式?
方法1 :对于循环外部任务 - 生成计算后台任务,每个任务运行几秒
@share_task
def my_task(usr):
#gen file + send email...
def send_to_all_users(users): # called to start task
for usr in users:
my_task.delay(usr)
方法2 :对于循环内部任务 - 生成1个可以运行数小时的后台任务
@share_task
def my_task(users):
for usr in users:
#gen file + send email...
def send_to_all_users(users): # called to start task
my_task.delay(users)
使用方法1,我可以扩大工作人员数量以更快地完成整个任务,但创建所有这些任务可能需要一段时间,我不确定我的任务队列是否可以填满,然后作业被丢弃?
方法2似乎更简单,但它可能会运行很长时间,我无法扩大工人数量。
不确定是否重要,但我的应用程序在Heroku上运行,而我正在使用Redis作为消息代理。我目前正在使用一名后台工作人员。
答案 0 :(得分:1)
Task Granularity上的芹菜文档:
任务粒度是每个所需的计算量 子任务。 一般情况下,最好将问题分解为多个 小任务,而不是一些长期运行的任务。
使用较小的任务,您可以并行处理更多任务 任务运行时间不足以阻止工作人员处理其他任务 等待任务。
但是,执行任务确实有开销。需要一条消息 发送,数据可能不是本地等,所以如果任务太细粒度 增加的开销可能会消除任何好处。
因此,第一种方法应该首选 ,但您必须对特定情况进行基准测试以评估开销。