Celery --beat на процессах Heroku vs Worker и Clock

У меня есть периодическая задача, которую я выполняю в файле heroku procfile с помощью worker:

Procile

web: gunicorn voltbe2.wsgi --log-file - --log-level debug
worker: celery -A voltbe2 worker --beat -events -loglevel info 

tasks.py

class PullXXXActivityTask(PeriodicTask):
    """
    A periodic task that fetch data every 1 mins.
    """
    run_every = timedelta(minutes=1)

    def run(self, **kwargs):
        abc= MyModel.objects.all()
        for rk in abc:
            rk.pull()
        logger = self.get_logger(**kwargs)
        logger.info("Running periodic task for XXX.")

        return True

Для этой периодической задачи мне нужен --beat (я проверил, отключив, и он не повторяет задачу). Итак, каким-то образом --beat выполняет работу часов (https://devcenter.heroku.com/articles/scheduled-jobs-custom-clock-processes).

Меня беспокоит: если я масштабирую worker heroku ps:scale worker=2 до 2x dynos, я вижу, что есть два такта, запущенных на worker.1 и worker.2 из журналов:

 Aug 25 09:38:11 emstaging app/worker.2: [2014-08-25 16:38:11,580: INFO/Beat] Scheduler: Sending due task apps.notification.tasks.SendPushNotificationTask (apps.notification.tasks.SendPushNotificationTask)
Aug 25 09:38:20 emstaging app/worker.1: [2014-08-25 16:38:20,239: INFO/Beat] Scheduler: Sending due task apps.notification.tasks.SendPushNotificationTask (apps.notification.tasks.SendPushNotificationTask) 

Отображаемый журнал предназначен для другой периодической задачи, но ключевым моментом является то, что оба рабочих динамометра получают сигналы для выполнения одной и той же задачи от своих соответствующих часов, в то время как на самом деле должны быть одни часы, которые тикают и через каждые XX секунд решают, что делать. делать, и передает эту задачу наименее загруженному worker.n дино

Подробнее о том, почему необходимы одни часы, можно найти здесь: https://devcenter.heroku.com/articles/scheduled-jobs-custom-clock-processes#custom-clock-processes.

Это проблема и как этого избежать?


person dowjones123    schedule 25.08.2014    source источник


Ответы (1)


У вас должен быть отдельный воркер для бит-процесса.

web: gunicorn voltbe2.wsgi --log-file - --log-level debug
worker: celery -A voltbe2 worker -events -loglevel info 
beat: celery -A voltbe2 beat 

Теперь вы можете масштабировать рабочую задачу, не влияя на битовую.

В качестве альтернативы, если вам не всегда нужен дополнительный процесс, вы можете продолжать использовать -B в рабочей задаче, но также иметь вторую задачу - скажем, extra_worker - для которой обычно установлено значение 0 dynos, но которое вы можете масштабировать как необходимо. Важно всегда держать задачу в ритме на 1 процессе.

person Daniel Roseman    schedule 25.08.2014
comment
Спасибо @Daniel. Итак, если я правильно понимаю, до тех пор, пока есть бит, который выдается ЛЮБЫМ из процессов Procfile, он будет распространяться по всему приложению, и все рабочие могут услышать этот «ритм»? Есть ли какой-нибудь документ на heroku, который это объясняет? - person dowjones123; 25.08.2014
comment
На самом деле это не имеет ничего общего с Heroku, и это не совсем ритм, который слушают другие работники. Скорее, «битовое» задание просто помещает все задания, которые должны быть выполнены, в очередь, а затем они подбираются работником (-ами) совершенно обычным образом. - person Daniel Roseman; 25.08.2014
comment
@DanielRoseman Спасибо за этот ответ, пожалуйста, не могли бы вы дать ссылку для дальнейшего чтения по этому поводу .. Кажется, я не могу найти что-либо в документации heroku. - person Subomi; 19.06.2018