Celery: Одна и та же задача выполняется несколько раз одновременно?

Созданный на 20 нояб. 2017  ·  43Комментарии  ·  Источник: celery/celery

Проблема заключается в повторном размещении сообщения в группе Google без присмотра _Одна и та же задача выполняется несколько раз?_

> ./bin/celery -A celery_app report

software -> celery:4.1.0 (latentcall) kombu:4.1.0 py:3.6.1
            billiard:3.5.0.3 redis:2.10.6
platform -> system:Linux arch:64bit, ELF imp:CPython
loader   -> celery.loaders.app.AppLoader
settings -> transport:redis results:redis://localhost:6379/2

broker_url: 'redis://localhost:6379/2'
result_backend: 'redis://localhost:6379/2'
task_serializer: 'json'
result_serializer: 'json'
accept_content: ['json']
timezone: 'Europe/Berlin'
enable_utc: True
imports: 'tasks'
task_routes: {
 'tasks': {'queue': 'celery-test-queue'}}

Мое приложение планирует одну группу из двух, а иногда и трех задач, каждая из которых имеет свое собственное расчетное время прибытия в течение одного часа. Когда прибывает ETA, я вижу в своем журнале celery следующее:

[2017-11-20 09:55:34,470: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 33.81780316866934s: None
[2017-11-20 09:55:34,481: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.009824380278587341s: None
[2017-11-20 09:55:34,622: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.14010038413107395s: None
…
[2017-11-20 09:55:37,890: INFO/ForkPoolWorker-8] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.012678759172558784s: None
[2017-11-20 09:55:37,891: INFO/ForkPoolWorker-2] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.01177949644625187s: None
[2017-11-20 09:55:37,899: INFO/ForkPoolWorker-8] Task tasks._test_exec[bd08ab85-28a8-488f-ba03-c2befde10054] succeeded in 0.008250340819358826s: None
…

Это может повторяться десятки раз. Обратите внимание на время выполнения первой задачи 33 секунды и использование разных рабочих!

У меня нет объяснения этому поведению, и я хотел бы понять, что здесь происходит.

Redis Broker Redis Results Backend Feedback Needed ✘ Needs Testcase ✘

Самый полезный комментарий

@georgepsarakis Итак, если задача запланирована далеко вперед, я могу увидеть вышеописанное? «Тайм-аут видимости» решает эту проблему? Из документации, которую вы связали:

Время ожидания видимости по умолчанию для Redis составляет 1 час.

Это означает, что если в течение часа воркер не подтвердит задачу (т.е. не запустит ее?), эта задача будет отправлена ​​другому воркеру, который не подтвердит, и т. д. Действительно, это похоже на тот случай, если посмотреть на раздел с предостережениями документация; эта связанная проблема https://github.com/celery/kombu/issues/337; или цитата из этого блога :

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

Похоже, установка visibility_timeout на 31 540 000 секунд (один год) может быть быстрым решением.

Все 43 Комментарий

Может быть, это связано с тайм-аутом видимости ?

@georgepsarakis Не могли бы вы уточнить свои подозрения?

Насколько я знаю, это известная проблема для транспортных брокеров, которые не имеют встроенных характеристик подтверждения AMQP. Задача будет назначена новому работнику, если время выполнения задачи превысит время ожидания видимости, таким образом, вы можете увидеть, что задачи выполняются параллельно.

@georgepsarakis Итак, если задача запланирована далеко вперед, я могу увидеть вышеописанное? «Тайм-аут видимости» решает эту проблему? Из документации, которую вы связали:

Время ожидания видимости по умолчанию для Redis составляет 1 час.

Это означает, что если в течение часа воркер не подтвердит задачу (т.е. не запустит ее?), эта задача будет отправлена ​​другому воркеру, который не подтвердит, и т. д. Действительно, это похоже на тот случай, если посмотреть на раздел с предостережениями документация; эта связанная проблема https://github.com/celery/kombu/issues/337; или цитата из этого блога :

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

Похоже, установка visibility_timeout на 31 540 000 секунд (один год) может быть быстрым решением.

Я бы сказал, что если вы увеличите таймаут видимости до 2 часов, ваши задачи будут выполняться только один раз.

Итак, если вы объедините:

  • Брокер Redis
  • Позднее подтверждение
  • Расчетное время прибытия равно/превыше тайм-аута видимости
    вы получаете несколько выполнений задачи.

Я думаю, что происходит:

  • По истечении часа один рабочий процесс начинает обработку задачи.
  • Второй рабочий процесс увидит, что это сообщение находится в очереди дольше, чем время ожидания видимости, и обрабатывается другим рабочим процессом.
  • Сообщение восстанавливается в очереди.
  • Другой рабочий процесс начинает обработку того же сообщения.
  • Вышеописанное происходит для всех рабочих процессов.

Глядя на реализацию транспорта Redis, вы заметите, что она использует Sorted Sets, передавая время в очереди в качестве оценки zadd . Сообщение восстанавливается на основе этой временной метки и сравнивается с интервалом, равным тайм-ауту видимости .

Надеюсь, это немного объясняет внутренности транспорта Redis.

@georgepsarakis , я совсем запутался. Если расчетное время выполнения задачи установлено на два месяца вперед, зачем работнику выполнять ее через час после того, как задачи были запланированы? Я что-то пропустил?

Мое (неверное?) предположение таково:

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

Ваше «_Я думаю, что происходит:_» выше сильно отличается от моего предположения.

Я тоже столкнулся с такой проблемой, вы решили ее? @jenstroeger

Спасибо!

@jenstroeger , это не похоже на осуществимый поток, я думаю, что рабочий просто постоянно запрашивает сообщение, чтобы отложить выполнение до тех пор, пока условие ETA не будет окончательно выполнено. Концепция очереди заключается в распределении сообщений по мере их поступления, поэтому рабочий процесс проверяет сообщение и просто помещает его в очередь.

Обратите внимание, что это мое предположение, я не совсем осведомлен о внутренностях реализации ETA.

@zivsu , как упоминалось выше , я установил для visibility_timeout _очень_ большое число, и это, похоже, устранило симптомы. Однако, как указывает @georgepsarakis , это плохой подход.

Я не знаю ни причину исходной проблемы, ни как решить ее должным образом.

@jenstroeger Я читал какой-то блог, изменение visibility_timeout не может полностью решить проблему, поэтому я меняю свой боркер на rabbitmq .

@zivsu , не могли бы вы поделиться ссылкой на блог? Вы использовали Redis раньше?

@jenstroeger Я не могу найти блог, раньше я использовал Redis в качестве брокера. Для задачи расписания я выбираю rebbitmq, чтобы избежать повторения ошибки.

У меня точно такая же проблема, мой конфиг:
Джанго == 1.11.6
сельдерей==4.2rc2
Джанго-сельдерей-бить == 1.0.1

настройки:

CELERY_ENABLE_UTC = True
# CELERY_TIMEZONE = 'America/Los_Angeles'

И это единственная рабочая комбинация этих настроек. Также я должен планировать свои периодические задачи в часовом поясе UTC.
Если вы включите CELERY_TIMEZONE или отключите CELERY_ENABLE_UTC , периодические задачи будут запускаться несколько раз.

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

При использовании Redis возникает известная проблема, когда вы указываете часовой пояс, отличный от UTC. Чтобы обойти эту проблему, создайте подкласс приложения по умолчанию и добавьте собственную функцию обработки часового пояса:

from celery import Celery


class MyAppCelery(Celery):
    def now(self):
        """Return the current time and date as a datetime."""
        from datetime import datetime
        return datetime.now(self.timezone)

Надеюсь, что это поможет любому, кто сталкивается с этой проблемой.

Я иногда сталкиваюсь с этой проблемой при частом перезапуске заданий celery с помощью beat на многоядерных машинах. У меня есть привычка запускать ps aux | grep celery , а затем kill <each_pid> , чтобы решить эту проблему.

Лучший совет, который я могу дать, это всегда убедиться, что вы видите сообщение «restart DONE» перед отключением от машины.

{"log":"INFO 2018-10-09 17:41:08,468 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T17:41:08.468912644Z"}
{"log":"INFO 2018-10-09 17:41:08,468 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T17:41:08.468955918Z"}
{"log":"INFO 2018-10-09 19:46:04,293 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T19:46:04.293780045Z"}
{"log":"INFO 2018-10-09 19:46:04,293 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T19:46:04.293953621Z"}
{"log":"INFO 2018-10-09 20:46:04,802 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T20:46:04.802819711Z"}
{"log":"INFO 2018-10-09 20:46:04,802 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T20:46:04.802974829Z"}
{"log":"INFO 2018-10-09 21:46:05,335 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T21:46:05.336081133Z"}
{"log":"INFO 2018-10-09 21:46:05,335 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T21:46:05.336107517Z"}
{"log":"INFO 2018-10-09 22:46:05,900 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T22:46:05.901078395Z"}
{"log":"INFO 2018-10-09 22:46:05,900 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T22:46:05.901173663Z"}
{"log":"INFO 2018-10-09 23:46:06,484 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T23:46:06.485276904Z"}
{"log":"INFO 2018-10-09 23:46:06,484 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-09T23:46:06.485415253Z"}
{"log":"INFO 2018-10-10 00:46:07,072 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T00:46:07.072529828Z"}
{"log":"INFO 2018-10-10 00:46:07,072 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T00:46:07.072587887Z"}
{"log":"INFO 2018-10-10 01:46:07,602 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T01:46:07.60325321Z"}
{"log":"INFO 2018-10-10 01:46:07,602 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T01:46:07.603327426Z"}
{"log":"INFO 2018-10-10 02:46:08,155 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T02:46:08.155868992Z"}
{"log":"INFO 2018-10-10 02:46:08,155 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T02:46:08.155921893Z"}
{"log":"INFO 2018-10-10 03:46:08,753 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T03:46:08.75401387Z"}
{"log":"INFO 2018-10-10 03:46:08,753 strategy celery.worker.strategy 1 140031597243208 Received task: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f]  ETA:[2018-10-10 04:00:00+00:00] \n","stream":"stderr","time":"2018-10-10T03:46:08.754056891Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.013548928Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.013592318Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:71\n","stream":"stderr","time":"2018-10-10T04:00:00.014000106Z"}
{"log":"DEBUG 2018-10-10 04:00:00,013 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:71\n","stream":"stderr","time":"2018-10-10T04:00:00.014167558Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:64\n","stream":"stderr","time":"2018-10-10T04:00:00.014661348Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:64\n","stream":"stderr","time":"2018-10-10T04:00:00.014684354Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.01514884Z"}
{"log":"DEBUG 2018-10-10 04:00:00,014 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.015249646Z"}
{"log":"DEBUG 2018-10-10 04:00:00,015 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:66\n","stream":"stderr","time":"2018-10-10T04:00:00.01571124Z"}
{"log":"DEBUG 2018-10-10 04:00:00,015 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:66\n","stream":"stderr","time":"2018-10-10T04:00:00.01580249Z"}
{"log":"DEBUG 2018-10-10 04:00:00,019 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:68\n","stream":"stderr","time":"2018-10-10T04:00:00.019260948Z"}
{"log":"DEBUG 2018-10-10 04:00:00,019 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:68\n","stream":"stderr","time":"2018-10-10T04:00:00.019322151Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.245159563Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:70\n","stream":"stderr","time":"2018-10-10T04:00:00.245177267Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:67\n","stream":"stderr","time":"2018-10-10T04:00:00.245338722Z"}
{"log":"DEBUG 2018-10-10 04:00:00,245 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:67\n","stream":"stderr","time":"2018-10-10T04:00:00.245351289Z"}
{"log":"DEBUG 2018-10-10 04:00:00,256 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.256770035Z"}
{"log":"DEBUG 2018-10-10 04:00:00,256 request celery.worker.request 1 140031597243208 Task accepted: main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] pid:65\n","stream":"stderr","time":"2018-10-10T04:00:00.256788689Z"}
{"log":"INFO 2018-10-10 04:00:00,371 trace celery.app.trace 68 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.35710329699213617s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.371967002Z"}
{"log":"INFO 2018-10-10 04:00:00,371 trace celery.app.trace 68 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.35710329699213617s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.371983293Z"}
{"log":"INFO 2018-10-10 04:00:00,387 trace celery.app.trace 69 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.10637873200175818s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.388119538Z"}
{"log":"INFO 2018-10-10 04:00:00,387 trace celery.app.trace 69 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.10637873200175818s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.388166317Z"}
{"log":"INFO 2018-10-10 04:00:00,404 trace celery.app.trace 70 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.16254851799749304s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.404834545Z"}
{"log":"INFO 2018-10-10 04:00:00,404 trace celery.app.trace 70 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.16254851799749304s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.404862208Z"}
{"log":"INFO 2018-10-10 04:00:00,421 trace celery.app.trace 65 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.1654666289978195s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.421607856Z"}
{"log":"INFO 2018-10-10 04:00:00,421 trace celery.app.trace 65 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.1654666289978195s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.421674687Z"}
{"log":"INFO 2018-10-10 04:00:00,438 trace celery.app.trace 67 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.19588526099687442s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.438295459Z"}
{"log":"INFO 2018-10-10 04:00:00,438 trace celery.app.trace 67 140031597243208 Task main.batch.sendspam[2a6e5dc8-5fd2-40bd-8f65-7e7334a14b3f] succeeded in 0.19588526099687442s: None\n","stream":"stderr","time":"2018-10-10T04:00:00.438311386Z"}
...

если мы проверим временные метки полученной задачи, каждый час она будет получать новую задачу с тем же идентификатором. В результате все сообщения ETA отправляются более 10 раз. Похоже, rabbitmq — единственный вариант, если мы хотим использовать ETA.

Недавно встречал подобный баг. Также ps aux | grep celery показывал больше процессов, чем запущено воркеров, в два раза больше. Добавление параметра --pool gevent к команде запуска сельдерейных воркеров снизило количество процессов до точного количества запущенных воркеров и celery beat. И теперь я слежу за выполнением своих задач.

Может ли другое решение полностью отключить эмуляцию ack? т.е. "broker_transport_options": {"ack_emulation": False} . Есть ли недостатки для кратковременных задач/обратных отсчетов?

Кто-нибудь получил исправление?

Столкнулся с такой же проблемой, есть решение?

Натыкаюсь, та же проблема.

Та же проблема здесь, используя Redis в качестве брокера.

$ pipenv graph --bare | grep -i "redis\|celery"                                                                                                                                                                                                                              
---
channels-redis==2.4.0
  - aioredis [required: ~=1.0, installed: 1.3.0]
    - hiredis [required: Any, installed: 1.0.0]
django-celery-beat==1.5.0
django-celery-results==1.1.2
  - celery [required: >=4.3,<5.0, installed: 4.3.0]
  - celery [required: >=3.1.0, installed: 4.3.0]
  - pylint-celery [required: ==0.3, installed: 0.3]
redis==3.2.1

Та же проблема здесь. Сельдерей версии 4.3.0
celery = Celery('tasks', broker='pyamqp://nosd:sdsd@rabbit//', config_from_object={"broker_transport_options":{'visibility_timeout': 18000}})

Команда, которую я использую для запуска своего рабочего
celery -A Task Worker --pidfile=/tmp/celery_worker.pid -f=/tmp/celery_worker.log -Q celery_queue --loglevel=info --pool=solo --concurrency=1 -n worker_celery --detach -- без сплетен --без общения --без сердцебиения

Вы можете попробовать celery == 4.4.0rc4?

Celery получает одну и ту же задачу дважды с одним и тем же идентификатором задачи в одно и то же время.
Вот журналы

[2019-11-29 08:07:35,464: INFO/MainProcess] Received task: app.jobs.booking.bookFlightTask[657985d5-c3a3-438d-a524-dbb129529443]  
[2019-11-29 08:07:35,465: INFO/MainProcess] Received task: app.jobs.booking.bookFlightTask[657985d5-c3a3-438d-a524-dbb129529443]  
[2019-11-29 08:07:35,471: WARNING/ForkPoolWorker-4] in booking funtion1
[2019-11-29 08:07:35,473: WARNING/ForkPoolWorker-3] in booking funtion1
[2019-11-29 08:07:35,537: WARNING/ForkPoolWorker-3] book_request_pp
[2019-11-29 08:07:35,543: WARNING/ForkPoolWorker-4] book_request_pp

оба работают одновременно,

используя celery==4.4.0rc4 , boto3==1.9.232, kombu==4.6.6 с SQS в колбе pyhton.
в SQS тайм-аут видимости по умолчанию составляет 30 минут, и моя задача не иметь ETA и не ack.

бегущий рабочий,
celery worker -A app.jobs.run -l info --pidfile=/var/run/celery/celery.pid --logfile=/var/log/celery/celery.log --time-limit=7200 --concurrency =8

@auvipy , любая помощь будет здоровой.

какого брокера и серверную часть результатов вы используете? можно попробовать переключиться на другой бэкенд?

какого брокера и серверную часть результатов вы используете? можно попробовать переключиться на другой бэкенд?

используя SQS, результатом является MYSQL с sqlalchemy.
подробности здесь, в SO, https://stackoverflow.com/questions/59123536/celery-is-receive-same-task-twice-with-same-task-id-at-same-time
@auvipy , не могли бы вы взглянуть.

@thedrow вы сталкиваетесь с этой проблемой в Блумберге?

@nitish-itilite: какой часовой пояс вы используете для сельдерея?

@nitish-itilite: какой часовой пояс вы используете для сельдерея?

это UTC по умолчанию. в sqs регион — это Восток США (Северная Вирджиния).

У меня был аналогичный случай с сельдереем с SQS. Я выполнил фиктивную задачу с countdown=60 , а время ожидания видимости в SQS составляет 30 секунд. Вот что я получаю:

ПРИМЕЧАНИЕ. Я начал celery с --concurrency=1 , так что есть два потока, верно?

[2020-02-18 14:46:32 +0000] [INFO] Received task: notification[b483a22f-31cc-4335-9709-86041baa8f05]  ETA:[2020-02-18 14:47:31.898563+00:00] 
[2020-02-18 14:47:02 +0000] [INFO] Received task: notification[b483a22f-31cc-4335-9709-86041baa8f05]  ETA:[2020-02-18 14:47:31.898563+00:00] 
[2020-02-18 14:47:32 +0000] [INFO] Task notification[b483a22f-31cc-4335-9709-86041baa8f05] succeeded in 0.012232275999849662s: None
[2020-02-18 14:47:32 +0000] [INFO] Task notification[b483a22f-31cc-4335-9709-86041baa8f05] succeeded in 0.012890915997559205s: None

Что произошло в хронологическом порядке:

  1. 14:46:32 задание получено, и SQS перевел его в режим inflight на 30 секунд
  2. 14:47:02 та же задача получена, так как время ожидания видимости истекло
  3. 14:47:32 обе задачи выполняются одновременно

Я предполагаю, что это ошибка в Celery (?), Я думаю, что он должен был проверить, был ли идентификатор сообщения ( b483a22f-31cc-4335-9709-86041baa8f05 ) уже принят этим работником.

Возможно, мог бы быть хеш-список со всеми идентификаторами сообщений, чтобы сельдерей мог решить, подходит ли полученная задача для обработки. Сельдерей так может?

ЗАМЕТКА 2:
Мы не можем установить тайм-аут видимости слишком долго, потому что, если работник действительно умрет, сообщение будет получено другим работником слишком долго. Установка слишком низкого значения приведет к возникновению этого состояния.

Кажется, это происходит и со мной.

[2020-05-11 15:31:23,673: INFO/MainProcess] Полученная задача: ee_external_attributes.tasks. воссоздать_специфические_значения[53046bd7-2a19-4f72-808f-d712eaecb0e8]
[2020-05-11 15:31:28,673: INFO/MainProcess] Полученная задача: ee_external_attributes.tasks.recreate_specific_values[53046bd7-2a19-4f72-808f-d712eaecb0e8]

(Я изменил название задачи в логах для публичной публикации.)

Из-за ограничений уникальности один из моих рабочих процессов выдает ошибку на полпути к выполнению задачи, а другой выполняет ее успешно.

Я попытался установить
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
Это оказалось не помочь.

я использую
сельдерей == 4.4.1
Джанго-сельдерей-результаты == 1.2.1

И я использую AWS SQS для очереди.

У меня есть теория. По-видимому, мой параметр «Тайм-аут видимости по умолчанию» в моей очереди был установлен только на 5 секунд. Возможно, второй рабочий снял работу, пока первый работал над ней, потому что предполагал, что первый рабочий умер. Я увеличил время ожидания видимости до 2 минут, и, похоже, стало лучше. У меня было много задач, которые занимали 8-12 секунд, поэтому 2 минуты могут быть излишними. Но, надеюсь, это решает.

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

@JulieGoldberg , это был бы отвратительный способ для Celery справляться с работой. Рабочий процесс Celery никогда не должен запускать задание, которое другой рабочий процесс вытащил из очереди и активно обрабатывает; думаю, что будет серьезно сломан. (Но это Сельдерей, меня уже ничему не удивишь 😒)

У меня похожая проблема с приложением, работающим в Kubernetes. В экземпляре Kubernetes у нас есть 10 рабочих процессов (экземпляр приложения celery), которые потребляют задачи из Redis.

Симптомы:
Работник celery планирует задачу ETA, которая будет запланирована через 30 минут. Если модуль Kubernetes ротируется (рабочий процесс уничтожается Kubernetes) или развертывается более новая версия приложения (все рабочие процессы удаляются и создаются новые рабочие процессы), все рабочие процессы возьмут запланированную задачу и начнут выполняться в определенное время.
Для воркера пробовал ставить разные значения visibility_timeout от нескольких часов до года, но результат был тот же. Такое же поведение было достигнуто с настройкой enable_utc = True или сокращением worker_prefetch_multiplier = 1 .

Я не знаю, поможет ли это кому-нибудь, но это была моя проблема:

У меня были задачи (генерация отчета), которые запускались при загрузке страницы через GET. По какой-то причине (что-то связанное с иконками) Chrome отправлял 2 запроса GET при каждой загрузке страницы, дважды запуская задачу.
Запросы GET должны быть свободны от побочных эффектов, поэтому я превратил их все в формы, которые вы отправляете, и проблема была решена.

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

@JulieGoldberg , это был бы отвратительный способ для Celery справляться с работой. Рабочий процесс Celery никогда не должен запускать задание, которое другой рабочий процесс вытащил из очереди и активно обрабатывает; думаю, что будет серьезно сломан. (Но это Сельдерей, меня уже ничему не удивишь 😒)

Вместо того, чтобы жаловаться, вы можете помочь нам решить проблему, предложив решение и PR.

У меня похожая проблема с приложением, работающим в Kubernetes. В экземпляре Kubernetes у нас есть 10 рабочих процессов (экземпляр приложения celery), которые потребляют задачи из Redis.

Симптомы:
Работник celery планирует задачу ETA, которая будет запланирована через 30 минут. Если модуль Kubernetes ротируется (рабочий процесс уничтожается Kubernetes) или развертывается более новая версия приложения (все рабочие процессы удаляются и создаются новые рабочие процессы), все рабочие процессы возьмут запланированную задачу и начнут выполняться в определенное время.

@elMateso Я столкнулся с похожими проблемами при развертывании Airflow на k8s (потребители в модулях и Redis в виде очереди). Но мне удалось сделать деплой стабильным и работающим как положено, может вам помогут эти советы:
https://www.polidea.com/blog/application-scalability-kubernetes/#tips-for-hpa

Здесь столкнулись с тем же.

Не похоже, что это проблема с какой-либо конфигурацией времени (тайм-аут видимости, ETA и т. Д.), По крайней мере, для меня. В моем случае это происходит через микросекунды между выполнениями. Не нашел, как сельдерей на самом деле делает ACK сообщение, но, если в rabbitMQ он работает отлично, похоже, это проблема с параллелизмом и ACK в Redis.

Я вижу ту же проблему, и мы также используем Redis в качестве брокера. Переход на rabbitMQ для нас не вариант.

Кто-нибудь пробовал использовать блокировку, чтобы задача выполнялась только один раз. Может ли это сработать?

например, https://docs.celeryproject.org/en/latest/tutorials/task-cookbook.html#ensuring -a-task-is-only-executed-one-at-time

@ErikKalkoken мы в конечном итоге делаем именно это.

def semaphore(fn):
    @wraps(fn)
    def wrapper(self_origin, *args, **kwargs):
        cache_name = f"{UID}-{args[0].request.id}-semaphore"
        agreement_redis = AgreementsRedis()
        if not agreement_redis.redis.set(cache_name, "", ex=30, nx=True):
          Raise Exception("...")
        try:
            return fn(self_origin, *args, **kwargs)
        finally:
            agreement_redis.redis.delete(cache_name)

    return wrapper

Приведенный выше код не используется для сельдерея, но множественное выполнение сельдерея — та же логика, вам просто нужно получить task_id и установить кеш. Пока работает нормально.

может кто-нибудь проверить этот пр https://github.com/vinayinvicible/kombu/commit/a755ba14def558f2983b3ff3358086ba55521dcc

Была ли эта страница полезной?
0 / 5 - 0 рейтинги