DjCelery и долгие задачи

Сегодня столкнулся с проблемой: часть задач отправлялась в celery, но не выполнялись, причем в rabbitmq-очередях была пустота – т.е. задачи были уже забраны в celery но не были выполнены, а в таблице celery_taskmeta эти задачи имели состояние PENDING.

Все дело оказалось в том, как celery раздает задачи child-процессам. По-умолчанию, задачи раздаются по-очереди, поэтому, например если у Вас есть celery-worker с двумя паралельными child-процессами, то задачи будут розданы им “по кругу” (а точнее, по round-robin):

drawingПричем, такой алгоритм будет применен независимо от того, свободен дочерний процесс или занят. А это означает, что если один из двух дочерних процессов будет занят бесконечно долгой задачей, то 50% отправленных задач вообще никогда не выполнятся, в то время как второй дочерний процесс выполнив свою половину задач будет простаивать.

Для обхода такого поведения celery имеет опцию “-Ofair”. Подробное описание опции находится здесь.

После запуска worker-ов с данной опцией раздача задач будет происходить по принципу “в следующий свободный обработчик”, а это в свою очередь очень полезно тогда, когда у вас есть “долгие” задачи.

Leave a Reply

Your email address will not be published. Required fields are marked *