Celery:众多小任务还是一项长期运行的任务?

Joh*_*han 6 django celery

我有一个 Django 应用程序并使用 Celery 来处理长时间运行的任务。

假设我需要生成一个文件(需要 5 秒),将其附加到电子邮件中并将其发送给 1000 个用户,以下哪种方法是首选方法?

方法 1:For 循环外部任务 - 生成计算后台任务,每个任务运行几秒钟

@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)
Run Code Online (Sandbox Code Playgroud)

方法 2:任务内的 For 循环 - 生成 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)
Run Code Online (Sandbox Code Playgroud)

使用方法 1,我可以扩大工作人员的数量以更快地完成整个任务,但创建所有这些任务可能需要一段时间,而且我不确定我的任务队列是否可以填满,然后作业会被丢弃?

方法2看起来更简单,但它可能会运行很长时间,而且我无法扩大工人的数量。

不确定这是否重要,但我的应用程序正在 Heroku 上运行,并且我使用 Redis 作为消息代理。我目前正在使用一个后台工作者。

sko*_*kin 7

关于任务粒度的 Celery 文档:

\n\n
\n

任务粒度是每个子任务所需的计算量。一般来说,最好将问题分解为许多小任务,而不是几个长时间运行的任务

\n\n

对于较小的任务,您可以并行处理更多任务,并且任务不会运行足够长的时间来阻止工作线程处理其他等待任务。

\n\n

然而,执行任务确实有开销。需要发送消息,数据可能不是本地的,等等。因此,如果任务粒度太细,增加的开销可能会消除任何好处。

\n
\n\n

因此,一般来说第一种方法应该是首选,但是您必须对您的特定情况进行基准测试以评估开销。

\n