Как предотвратить хранение объектов счетчика аккордов сельдерея в базе данных
Я столкнулся с проблемой, когда таблица django_celery_results_chordcounter
быстро заполняется, что приводит к нехватке места на сервере. Она увеличивалась от нескольких мегабайт до более чем 99 ГБ.
Я пытался решить эту проблему, установив CELERY_RESULT_EXPIRE=60
в надежде, что задача очистки бэкенда celery поможет мне очищать таблицу каждую минуту, но этого не происходило.
Я запустил задачу и к тому времени, когда таблица выросла примерно до 7 ГБ, я усек ее в оболочке psql. Это определенно не решение, но я должен был сделать это, чтобы задача могла быть успешной без увеличения ресурсов сервера.
Вот задачи сельдерея, приводящие к этой проблеме. Предметов может быть от сотен тысяч до миллионов.
Технические характеристики сервера: 16vCPUs, 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
}