我遇到了一个问题,
django_celery_results_chordcounter
表很快就填满了,导致我耗尽了服务器空间。它从几 MB 增长到超过 99 GB。
我尝试通过设置
CELERY_RESULT_EXPIRE=60
来解决这个问题,希望 celery 后端清理任务能够帮助我每分钟清理一次桌子,但这并没有发生。
我运行了该任务,当表增长到大约 7GB 时,我在 psql shell 上截断了它。这绝对不是一个解决方案,但我必须这样做,以便任务能够在不增加服务器资源的情况下成功。
以下是导致此问题的 celery 任务。物品可以是数十万到数百万。
服务器规格:16vCPU、64GiB 内存
@celery_app.task(ignore_result=True)
def get_for_one(item_id):
# an IO-bound task
pass
@celery_app.task(ignore_result=True)
def get_for_many(parent_id):
tasks = [
group(
get_for_one.s(item.id)
for item in Item.objects.filter(
owner__isnull=True, parent_id=parent_id
).iterator()
)
]
chord(tasks)(get_for_many_callback.si(parent_id))
celery==5.2.7
Django==4.1.1
django-celery-beat==2.4.0
django-celery-results==2.4.0
Celery 默认情况下每天凌晨 4 点运行内置的清理定期任务,因此它不一定会在结果过期后立即清理它们(而是等到下一次计划的清理)。
如果您想更频繁地运行清理任务,您可以在
CELERY_BEAT_SCHEDULE
中安排自己的间隔:
from datetime import timedelta
CELERY_BEAT_SCHEDULE = {
'Custom Celery result cleanup': {
'task': 'celery.backend_cleanup',
'schedule': timedelta(seconds=60),
},
#...your other schedules
}
注意:这只会在现有(默认)Celery 清理计划之上添加您的自定义计划,该计划仍会在每天凌晨 4 点发生。这不是问题,只要记住就好。