Как настроить очередь sidekiq для запуска только задачи одновременно - PullRequest
0 голосов
/ 21 марта 2019

Я использую Sidekiq в своем приложении на Rails для обработки фоновых заданий.

sidekiq.yml

:verbose: false
:pidfile: ./tmp/pids/sidekiq.pid
:logfile: ./log/sidekiq.log
:concurrency: 5
:queues:
  - ["queue1", 1]
  - ["queue2", 1]
  - ["queue3", 1]
  - ["queue4", 1]
  - ["queue5", 1]
  - critical
  - default
  - low
max_retries: 1

Я хочу запускать только одну задачу в очереди за раз.

Например: я запускаю одного и того же работника 3 раза в очереди 1, хочу обработать worker1, а затем worker2, а затем worker3.

Я добавил «1» с именем очереди (например, ["queue1", 1]) в sidekiq.yml.Я думал, что эта конфигурация будет запускать только один рабочий в queue1.Но этого не происходит.

Как выполнить вышеуказанную конфигурацию в sidekiq?

Ответы [ 7 ]

1 голос
/ 26 марта 2019

Просто используйте встроенный ActiveJob , потому что это звучит так, как будто вы хотите очередь FIFO. Sidekiq для идемпотентного одновременного фона

1 голос
/ 26 марта 2019

Sidekiq явно не разрешает делать то, что вы хотите.

https://github.com/mperham/sidekiq/wiki/Best-Practices#3-embrace-concurrency

0 голосов
/ 01 апреля 2019

Сначала небольшое исправление в терминологии. «Рабочие» - это постоянно запущенные потоки, которые потребляют «задания» из «очередей». Следовательно, вы не обрабатывает worker1, вместо этого worker1 будет обрабатывать задания из очереди 1.

Теперь подходим к решению: -

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

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

Я использовал «sidekiq-lock» на базе Redis для достижения чего-то похожего в моих проектах.

Gem Link

Использование выглядит следующим образом: -

class Worker
  include Sidekiq::Worker
  include Sidekiq::Lock::Worker

  # static lock that expires after one second
  sidekiq_options lock: { timeout: 1000, name: 'unique-lock-name' }

  def perform
    # your code to upload to s3
  end
end

Это обеспечит выполнение вашим кодом только одного экземпляра заданий на одном работнике за раз.

0 голосов
/ 30 марта 2019

Вы можете использовать sidekiq-limit_fetch , чтобы использовать расширенные опции для sidekiq.Чтобы ограничить параллелизм в отдельной очереди, вы можете сделать следующее.

Шаг 1. Добавьте gem 'sidekiq-limit_fetch' в свой Gemfile

Шаг 2. Добавьте ограничения для каждой очереди в вашем sidekiq.yml

:limits: queue1: 1 queue2: 1 queue3: 1 queue4: 1

0 голосов
/ 28 марта 2019

Я думаю это , что вы хотите функция

Добавьте его в свой рабочий класс

class YourWorker
  include Sidekiq::Worker
  sidekiq_options queue: :queue1

Но есть предостережение, которое работник может поставить в очередь только в очередь1.

0 голосов
/ 27 марта 2019

Установите параллелизм Sidekiq на 1. Таким образом, в вашем процессе будет работать только 1 поток, который даст вам желаемый результат: только 1 задание выполняется за один раз.

Просто измените свой конфигурационный файл:

:verbose: false
:pidfile: ./tmp/pids/sidekiq.pid
:logfile: ./log/sidekiq.log
:concurrency: 1 # Change Here
:queues:
  - ["queue1", 1]
  - ["queue2", 1]
  - ["queue3", 1]
  - ["queue4", 1]
  - ["queue5", 1]
  - critical
  - default
  - low
max_retries: 1
0 голосов
/ 26 марта 2019

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

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

Чтобы ограничить определенные параллельные задания очереди в пределах одного рабочего - вы можетеиспользуйте gem sidekiq-limit_fetch и такие настройки, как:

:limits:
  queue1: 1
  queue2: 1
...