Задача сельдерея / логика рабочего назначения - PullRequest
0 голосов
/ 14 февраля 2019

Привет, люди, работающие с stackoverflow!

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

У меня есть приложение, которое отправляет файлы клиентам по нескольким протоколам (FTP (S), SFTP, S3, EMail).

В каждом каталоге есть задача сельдерея.Каталог может быть отправлен нескольким клиентам и может быть отправлен нескольким адресатам.например, dir1 -> client1 -> FTP и EMail (2 задачи, нормально работать параллельно), dir2 -> client1 И client2 -> одно и то же имя хоста FTP, разные удаленные каталоги (2 задачи, плохо работать параллельно).

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

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

Моя первоначальная идея - реализовать удаленное управление очередью celery_worker.Одна очередь для каждой учетной записи, протокол.И настройте рабочих с параллелизмом 1, слушающих очереди.

Интересно, сталкивался ли кто-либо из вас с подобным вызовом и как вы его обошли.

1 Ответ

0 голосов
/ 14 февраля 2019

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

Существует довольно много рецептов (от довольно неофициальных советов до полномасштабных библиотек, таких как celery-Once), чтобы предотвратить одновременное выполнение одной данной задачи.Они напрямую не решают вашу собственную проблему, но в принципе принцип тот же: имейте некоторый механизм общей блокировки, с которым задачи взаимодействуют - попробуйте получить блокировку, запустить только после того, как она получена, и, конечно, отпустить ее.Если вы используете Redis в качестве бэкэнда результата, это довольно низкая стоимость чтения / записи, и его функция «expire» может быть действительно полезной, но вы также можете просто использовать свою базу данных SQL.

...