Работа вокруг сельдерея, являющегося единственной точкой отказа - PullRequest
16 голосов
/ 15 февраля 2012

Я ищу рекомендуемое решение для обхода celerybeat, являющегося единственной точкой отказа для развертывания celery / rabbitmq.Пока что я не нашел ничего, что имело бы смысл, просматривая в Интернете.

В моем случае, один раз в день планировщик запускает серию заданий, которые могут выполняться полдня или дольше.Поскольку может существовать только один экземпляр celerybeat, если что-то случится с ним или с сервером, на котором он запущен, критические задания не будут выполняться.

Я надеюсь, что для этого уже есть работающее решение, так как яне может быть единственным, кому нужен надежный (кластерный или подобный) планировщик.Я не хочу прибегать к какому-либо планировщику, поддерживаемому базой данных, если мне не нужно.

1 Ответ

5 голосов
/ 18 октября 2012

По этому поводу в репозитории celery github есть открытый вопрос.Не знаю, работают ли они над этим, хотя.

В качестве обходного пути вы можете добавить блокировку для задач, чтобы одновременно запускался только 1 экземпляр конкретного PeriodicTask.

Что-то вроде:

if not cache.add('My-unique-lock-name', True, timeout=lock_timeout):
    return

Выяснить время ожидания блокировки довольно сложно.Мы используем 0,9 * task run_every секунд, если разные сельдереи будут пытаться запускать их в разное время.0,9 только для того, чтобы оставить некоторый запас (например, когда сельдерей немного отстает от графика один раз, то он идет по расписанию, что приведет к тому, что блокировка все еще активна).

Тогда вы можете использовать экземпляр сельдерея на всех машинах.Каждая задача будет поставлена ​​в очередь для каждого экземпляра celerybeat, но только одна из них завершит выполнение.

Задачи все равно будут учитывать run_every таким образом, в худшем случае: задачи будут выполняться с 0,9 * run_every speed.

Одна проблема в этом случае: если задачи были поставлены в очередь, но не были обработаны в запланированное время (например, из-за недоступности процессоров очереди) - тогда блокировка может быть установлена ​​в неправильное время, что может привести к тому, что 1 следующая задача просто не будет запущена.Чтобы обойти это, вам понадобится какой-то механизм обнаружения, является ли задача более или менее своевременной.

Тем не менее, это не должно быть обычной ситуацией при использовании в производстве.

Другое решениеявляется подклассом планировщика сельдерея и переопределить его метод тиков.Затем для каждого тика добавить блокировку перед обработкой задач.Это гарантирует, что только сельдереи с одинаковыми периодическими задачами не будут ставить в очередь одни и те же задачи несколько раз.Только один сельдерей для каждого тика (тот, кто победит в состоянии гонки) поставит в очередь задачи.В одном сельдерее происходит сбой, при следующем тикете другой выигрывает гонку.

Это, конечно, можно использовать в сочетании с первым решением.

Конечно, чтобы это работало, нужно кеш-бэкэндареплицироваться и / или совместно использоваться для всех серверов.

Это старый вопрос, но я надеюсь, что он кому-нибудь поможет.

...