【问题标题】:Django - how to set up asynchronous longtime background data processing task?Django - 如何设置异步长时间后台数据处理任务?
【发布时间】:2012-11-26 16:09:01
【问题描述】:

关于 Django 应用程序设计的新问题:

我正在为我的网站构建报告引擎。而且我有大量(并且随着时间的推移越来越大)的数据,以及一些必须应用于它的算法。计算肯定会占用大量资源,如果它们是由用户请求执行的,那将是愚蠢的。所以,我想把它们放到后台进程中,它会连续执行并不时返回结果,这可以提供给 Django 视图例程,以便按需生成 html 输出。

我的问题是 - 构建此类系统的正确设计方法是什么?有什么想法吗?

【问题讨论】:

  • 你研究过 Celery 吗?可以用来调度任务!

标签: python django background-process backend


【解决方案1】:

您的意思是将结果返回到数据库中,还是您想直接从您独立运行的代码中创建 django-views?

如果您有大量数据,我喜欢使用 Pythons multiprocessing。您可以创建一个生成器,它用要执行的不同任务和一个使用不同任务的工人池填充 JoinableQueue。这样,您应该能够最大限度地利用系统上的资源。

多处理模块还允许您通过网络执行多项任务(例如multiprocessing.Manager())。考虑到这一点,如果您需要第二台机器及时处理数据,您应该能够轻松地扩大规模。

示例:

这个例子展示了如何产生多个进程。生成器函数应该查询数据库中所有需要繁重工作的新条目。消费者从队列中取出单个项目并进行实际计算。

import time 

from multiprocessing.queues import JoinableQueue
from multiprocessing import Process

QUEUE = JoinableQueue(-1)

def generator():
    """ Puts items in the queue. For example query database for all new, 
    unprocessed entries that need some serious math done.."""
    while True: 
        QUEUE.put("Item")
        time.sleep(0.1)


def consumer(consumer_id):
    """ Consumes items from the queue... Do your calculations here... """
    while True: 
        item = QUEUE.get()
        print "Process %s has done: %s" % (consumer_id, item)
        QUEUE.task_done()


p = Process(target=generator)
p.start()

for x in range(0, 2): 
    w = Process(target=consumer, args=(x,))
    w.start()

p.join()
w.join()

【讨论】:

  • "您的意思是结果被返回到数据库中,还是您想直接从您独立运行的代码中创建 django-views?"比无缝集成更好。
  • 既然你说需要处理的数据量很大,我建议你把数据保存到数据库中,从django中查询数据库。这样,如果您使用多处理并且数据被持久化,则无需创建额外的通信方式。例如,您只能使用 django 的一部分从其他代码部分访问数据库,如 stackoverflow.com/questions/937742/use-django-orm-as-standalonestackoverflow.com/questions/302651/… 中所述。
  • 我的困惑在于如何在 django 中调用该后台进程,注意它必须不受请求限制 - 如何在服务器启动(或按计划)启动并执行该进程连续吗?
  • 啊!现在我懂了。对困惑感到抱歉。我建议你在你的数据库中设置一个标志,上面写着“工作需要完成”。然后后台任务只需查询您的数据库以获取打开任务的列表。我添加了一个带有消费者/生成器的示例,应该稍微展示一下原理。此过程将手动启动或作为服务/守护程序启动。让它连续运行可以通过无限循环来完成(例如while True:)。只要确保你有某种停止条件,这样你就可以优雅地终止:)
  • 这个过程可以放在 Django 运行时,还是它的错误决定? ps 顺便谢谢你!
【解决方案2】:

为什么您没有一个 url 或 python 脚本来触发您每次运行时需要执行的任何类型的计算,然后获取该 url 或通过服务器上的 cronjob 运行该脚本?从您的问题来看,您似乎不需要更多。

【讨论】:

    【解决方案3】:

    芹菜是您最好的选择之一。我们正在成功使用它。它具有强大的调度机制 - 您可以将任务安排为定时作业,也可以在用户(例如)请求时在后台触发任务。

    它还提供了查询此类后台任务状态的方法,并具有许多流控制功能。它允许非常轻松地分配工作 - 即您的 celery 后台任务可以在单独的机器上运行(这对于例如 heroku web/workers 拆分非常有用,其中 web 进程限制为每个请求最多 30 秒)。它提供了各种队列后端(它可以使用数据库、rabbitMQ 或许多其他队列机制。通过最简单的设置,它可以使用您的 Django 站点已经使用的相同数据库(这使得设置变得容易)。

    如果您使用自动化测试,它还具有有助于测试的功能 - 可以设置为“急切”模式,后台任务不在后台执行 - 从而提供可预测的逻辑测试。

    更多信息在这里:http://docs.celeryproject.org:8000/en/latest/django/

    【讨论】:

      猜你喜欢
      • 2011-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-11
      • 2014-12-20
      • 2022-09-25
      • 1970-01-01
      相关资源
      最近更新 更多