【问题标题】:Celery: Numerous small tasks or one long running task?Celery:许多小任务还是一项长期运行的任务?
【发布时间】:2018-02-10 11:27:32
【问题描述】:

我有一个 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)

方法 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)

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

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

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

【问题讨论】:

    标签: django celery


    【解决方案1】:

    Task Granularity 上的 Celery 文档:

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

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

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

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

    【讨论】:

    • 非常感谢。也许最好将它分批发送给后台工作人员,例如每个后台作业 100 个条目
    • 我会从每个用户的任务开始(第一种方法),只有在真正需要时才进行批处理。也许我什至会将my_task 拆分为gen_filesend_email 子任务以获得更多控制,例如单独的队列和工作人员:一个用于文件生成的多处理池,另一个用于电子邮件发送的async pool
    猜你喜欢
    • 2020-09-02
    • 2011-09-15
    • 2013-06-07
    • 2021-02-05
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 2016-12-28
    • 2015-11-22
    相关资源
    最近更新 更多