如何限制 django 网站的 redis/celery 任务?
How to throttle redis/celery tasks for a django web site?
我有一个 django v3.0.2 站点 (python v3.6.9),我在其中上传图像、处理图像,然后将其显示在网站上。通过处理图像,我创建不同尺寸的图像,查找和识别面部,ocr 任何文本并在需要时进行翻译,使用几种不同的算法来计算每张图像与其他图像的相似程度,以及其他图像处理算法。我使用 celery v4.3.0 和 redis v4.0.9 在不同的 celery 任务中在后台进行所有计算。
我遇到的问题是,当我尝试在一个循环中上传和处理超过 ~4 张图像时,我 运行 内存不足并且计算开始抛出异常。由于 运行 内存不足,我的 5 GB 交换空间和 16 GB 内存都用完了,chrome 甚至崩溃了。在我的数据库中,我记录了每项任务的进度以及是否成功完成。我可以看到很多错误和很多任务没有开始。
如果我在上传图片的循环中放置一个 time.sleep(10)
,并且在 celery workers 为每张图片启动后立即上传,我可以在同一个循环中上传 60 多张图片而不会出现任何异常、崩溃或错误在我的任务日志中。
我在谷歌上搜索了一些方法来限制 celery 中的 worker,这样我就不必使用 sleep
,并且发现 celery 可能没有这种能力 Celery rate limiting with multiple workers in the celery issues forum. I found this article that might help Celery throttling - setting rate limit for queues。
在我像上面的参考一样开始自己构建一些东西之前,我想我会问集体意识是否有比 time.sleep(10)
更好的(对吗?)扼杀芹菜工人的方法所以我不知道't 运行 内存不足并产生大量任务错误。
这里 post 的代码太多了,下面是我正在做的事情的概述。
admin.py
def save_model(self, request, obj, form, change):
if form.is_valid():
if not change:
files = request.FILES.getlist('storage_file_name')
for f in files:
obj = Document() # model for each image
# add some data to the model
obj.save()
time.sleep(10)
doc_admin_workflow(<some parameters>)
else:
# some different housekeeping on the model fields
doc_admin_workflow(<some different parameters>)
super().save_model(request, obj, form, change)
def doc_admin_workflow(<some parameters>):
if not change:
# Decide which of the image processing steps to perform.
# Each processing step is a celery task of the form task_name.si(params)
# in a list called 'jobs' ~ 3-5 tasks
transaction.on_commit(lambda: chain(group(jobs),
change_state_task.si(document_id, 'new')).delay())
time.sleep(10)
else:
# decide what other processing steps (i.e. celery tasks) to perform
transaction.on_commit(lambda: chain(step_1, step_2, faces_2, ocr_job,
change_state_task.si(document_id, 'ready')).delay())
time.sleep(10)
上面使用的所有 celery 任务都是自包含的,因为它们不会将数据传递给下一个任务,也不会以任何方式相互交互。他们只是计算 read/write 数据库。
此外,这些上传是由网站管理员完成的。与站点交互的用户不会将图像上传到站点,也不会使用图像处理 celery 任务。所以,time.sleep(10)
是一个可能的解决方案,但它似乎是一个巨大的障碍,而且不是很稳健。
谢谢!
请参阅此相关post的答案:
把所有的和弦和组从我的任务中取出来,仅仅使用链似乎已经解决了 运行 内存不足的问题。现在不需要限制 celery 任务,也不需要将任何 time.sleep()
语句放入流程中。
我有一个 django v3.0.2 站点 (python v3.6.9),我在其中上传图像、处理图像,然后将其显示在网站上。通过处理图像,我创建不同尺寸的图像,查找和识别面部,ocr 任何文本并在需要时进行翻译,使用几种不同的算法来计算每张图像与其他图像的相似程度,以及其他图像处理算法。我使用 celery v4.3.0 和 redis v4.0.9 在不同的 celery 任务中在后台进行所有计算。
我遇到的问题是,当我尝试在一个循环中上传和处理超过 ~4 张图像时,我 运行 内存不足并且计算开始抛出异常。由于 运行 内存不足,我的 5 GB 交换空间和 16 GB 内存都用完了,chrome 甚至崩溃了。在我的数据库中,我记录了每项任务的进度以及是否成功完成。我可以看到很多错误和很多任务没有开始。
如果我在上传图片的循环中放置一个 time.sleep(10)
,并且在 celery workers 为每张图片启动后立即上传,我可以在同一个循环中上传 60 多张图片而不会出现任何异常、崩溃或错误在我的任务日志中。
我在谷歌上搜索了一些方法来限制 celery 中的 worker,这样我就不必使用 sleep
,并且发现 celery 可能没有这种能力 Celery rate limiting with multiple workers in the celery issues forum. I found this article that might help Celery throttling - setting rate limit for queues。
在我像上面的参考一样开始自己构建一些东西之前,我想我会问集体意识是否有比 time.sleep(10)
更好的(对吗?)扼杀芹菜工人的方法所以我不知道't 运行 内存不足并产生大量任务错误。
这里 post 的代码太多了,下面是我正在做的事情的概述。
admin.py
def save_model(self, request, obj, form, change):
if form.is_valid():
if not change:
files = request.FILES.getlist('storage_file_name')
for f in files:
obj = Document() # model for each image
# add some data to the model
obj.save()
time.sleep(10)
doc_admin_workflow(<some parameters>)
else:
# some different housekeeping on the model fields
doc_admin_workflow(<some different parameters>)
super().save_model(request, obj, form, change)
def doc_admin_workflow(<some parameters>):
if not change:
# Decide which of the image processing steps to perform.
# Each processing step is a celery task of the form task_name.si(params)
# in a list called 'jobs' ~ 3-5 tasks
transaction.on_commit(lambda: chain(group(jobs),
change_state_task.si(document_id, 'new')).delay())
time.sleep(10)
else:
# decide what other processing steps (i.e. celery tasks) to perform
transaction.on_commit(lambda: chain(step_1, step_2, faces_2, ocr_job,
change_state_task.si(document_id, 'ready')).delay())
time.sleep(10)
上面使用的所有 celery 任务都是自包含的,因为它们不会将数据传递给下一个任务,也不会以任何方式相互交互。他们只是计算 read/write 数据库。
此外,这些上传是由网站管理员完成的。与站点交互的用户不会将图像上传到站点,也不会使用图像处理 celery 任务。所以,time.sleep(10)
是一个可能的解决方案,但它似乎是一个巨大的障碍,而且不是很稳健。
谢谢!
请参阅此相关post的答案:
把所有的和弦和组从我的任务中取出来,仅仅使用链似乎已经解决了 运行 内存不足的问题。现在不需要限制 celery 任务,也不需要将任何 time.sleep()
语句放入流程中。