【问题标题】:Celery task seems to do everything except write to the database除了写入数据库之外,Celery 任务似乎可以做所有事情
【发布时间】:2011-07-23 21:10:57
【问题描述】:

我正在将 Django 与 MongoEngine、django-celery 和用于 celery 的 MongoDB 后端一起使用。我正在排队一项任务。该任务涉及从 GridFS 获取文件(通过 MongoEngine FileField),对其进行操作并将其放回数据库中。

任务按预期运行,无需排队。当我排队时,它会转换文件,但不会写入数据库。

这是我的 settings.py 的相关部分。

#These are apparently defaults that I shouldn't need
BROKER_BACKEND = 'mongodb'
BROKER_HOST = "localhost"
BROKER_PORT = 27017
BROKER_USER = ""
BROKER_PASSWORD = ""
BROKER_VHOST = ""

CELERY_RESULT_BACKEND = "mongodb" CELERY_MONGODB_BACKEND_SETTINGS = {
    "host": "localhost",
    "port": 27017,
    "database": "svg",
    "taskmeta_collection": "taskmeta", }

import djcelery djcelery.setup_loader()

我就是这样跑芹菜的

 $ ./manage.py celeryd -l info

当它运行任务时,celery 会这样说

[2011-07-23 16:07:11,858: INFO/MainProcess] Got task from broker: graphics.tasks.queue_convert[dfdf98ad-0669-4027-866d-c64971bb6480]
[2011-07-23 16:07:15,196: INFO/MainProcess] Task graphics.tasks.queue_convert[dfdf98ad-0669-4027-866d-c64971bb6480] succeeded in 3.33006596565s

(没有错误)

这是任务。

@task()
def queue_convert(imageId):
    image=Image.objects.get(id=imageId)
    convert(image)

convert 调用了许多其他函数。基本上,它首先从 FileField 读取,操作该字符串,将该字符串写入文件,操作该文件,将生成的字符串和文件写入其他 FileField,然后运行 ​​image.save()。

根据我是否将任务排队,mongo 日志看起来会有所不同。这是我使用任务队列时 mongo 日志中发生的情况。

Sat Jul 23 16:03:26 [initandlisten] connection accepted from 127.0.0.1:39065 #801
Sat Jul 23 16:03:26 [initandlisten] connection accepted from 127.0.0.1:39066 #802
Sat Jul 23 16:03:29 [initandlisten] connection accepted from 127.0.0.1:39068 #803

当我直接调用 convert(image) 而不是调用 queue_convert(image.id) 时会发生这种情况

Sat Jul 23 16:07:13 [conn807] end connection 127.0.0.1:43630
Sat Jul 23 16:07:13 [initandlisten] connection accepted from 127.0.0.1:43633 #808
Sat Jul 23 16:07:13 [initandlisten] connection accepted from 127.0.0.1:43634 #809
Sat Jul 23 16:07:13 [conn808] end connection 127.0.0.1:43633

知道可能出了什么问题吗?

【问题讨论】:

  • 我想看到convert 的代码可能会更加启发这个案例......
  • 我最终只是将文件与图像文档一起存储,而不是通过 FileField 与 gridfs 一起存储。有帮助的一件事是将调用转移到任务而不是导入函数,因为当它们在导入函数中时,有时会默默地失败。最终,我收到一条错误消息,提示 FileField.put 期望我传递编码,这没有意义。

标签: django mongodb celery django-celery mongoengine


【解决方案1】:

更新:我已经考虑过您遇到的更多问题,虽然听起来您已经为您解决了,但我会添加一些注释以防有人遇到类似问题。

Mongodb 显式扩展 JSON,改用“BSON”,它将二进制和文件类型添加到支持的类型列表中。我只在 celery 文档中看到过“JSON”,所以我猜想将 mongodb 与 celery 一起使用并处理扩展集需要小心,因为这听起来像是在处理图像。

在 IPYTHON (11.0rc4) 的最新开发版本的文档中,他们讨论了他们的分布式工作系统。尽管术语听起来与 celery 相似,但后端可能完全不同。我认为 celery 在后端方面相对灵活,并且可能允许更高的安全性,这听起来像是 ipython 需要的 zeromq 的问题。但在数据库方面,根据文档,ipython 系统是“围绕 mongodb 从头开始​​设计的”,并且完全支持 bson。因此,如果您不太关心其他 celery 功能(当然,安全性、与 django 相关的开发基础等等),您可以研究一下。同样,这绝不是 celery 和 ipython 都应得的严格评估,只是可能的领先; ipython 还与其他科学计算库很好地集成,内置对 matplotlib 的支持,以及许多科学计算示例,如果您正在进行图像处理并将图像数据视为 numpy 数组或其他任何东西,您可能会感兴趣。

祝你好运

原答案: 我同意 lazerscience - 这将有助于在这里有更多的背景。由于这些库的复杂性,有很多未知数。可能无法以本网站所期望的严谨回答。

也就是说,我认为您可能遇到了序列化问题。 Celery 要求您的对象是可腌制的,或者至少可以根据您选择的任何实现进行序列化(我知道它们也支持 JSON,尽管我已经够新手不确定 Pickle 和 JSON 是否完全重叠)。我看到你的函数只需要一个整数参数,这很好。但是转向 gridfs 是否意味着您正在尝试腌制图像?你当然可以用 celery 操作图像,但我不确定,尤其是在神秘的“转换”函数背后发生的一切,你是否可能不小心尝试序列化除 unicode、字典、整数、浮点数等以外的东西您的格式将支持的其他一些杂项对象。也许您过去检索了图像的文件路径并在文件中对其进行了操作,而无需检索或发送超过 unicode 的文件,而现在拥有图像本身?

如果我离基地太远了,请放慢我的脚步。我之所以做出回应,是因为我在这里和 mongoengine 用户组上都看到了您的消息,并认为您被卡住了,没有找到更专业的意见。您还可以仔细检查以确保您拥有相当最新的后端软件版本。在某个时候,我遇到了一堆奇怪的 celery 问题,发现它们主要在我更新 rabbitmq 时得到了解决。祝你好运!

【讨论】:

    猜你喜欢
    • 2019-11-26
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多