К утру в очереди 40...
 
Уведомления
Очистить всё

К утру в очереди 40 тысяч джоб: ночной импорт забивает всё

6 Сообщения
5 Пользователи
6 Реакции
595 Просмотры
Улугбек Макаров
Сообщения: 5
Автор темы
Пишет в irb разработчик
Присоединился: 4 года назад
[#28]

Roda, Sequel, Sidekiq 7, Redis. В 2:00 крон запускает импорт прайсов от поставщиков, он ставит по джобе на каждый товар, выходит около 60 тысяч. Всё в одну очередь default. К семи утра там ещё 40 тысяч, и письма с подтверждением регистрации, которые тоже в default, уходят людям через час. Пока ехал утром с Гражданки, поддержка уже переслала три жалобы. Конфиг сейчас:

:concurrency: 10
:queues:
  - default

Сервер один, 4 ядра. Что разумнее: добавить потоков или делить очереди?


5 ответов
GalinaKorneva
Сообщения: 30
Читает чужие PR бэкенд-разработчица
Присоединился: 4 года назад

Сначала делить. Письма и всё, чего ждёт человек, в отдельную очередь, импорт в свою с низким весом. Веса в Sidekiq работают так, что низкая очередь не голодает, но и не мешает:

:concurrency: 10
:queues:
  - [critical, 6]
  - [default, 3]
  - [import, 1]

Ещё лучше отдельный процесс Sidekiq только под import со своим concurrency, тогда импорт вообще не занимает потоки писем. И посмотрите, во что упирается импорт: если в базу, лишние потоки сделают только хуже.


Ответ
alisher1996
Сообщения: 6
Пишет в irb архитектор
Присоединился: 3 года назад

60 тысяч джоб на 60 тысяч товаров тоже перебор. Бейте на пачки по 500 и пишите одним upsert на пачку, будет 120 джоб


Ответ
Улугбек Макаров
Сообщения: 5
Автор темы
Пишет в irb разработчик
Присоединился: 4 года назад

Сделал оба совета. Импорт кладёт джобы пачками по 500 товаров в очередь import, у неё отдельный процесс Sidekiq с concurrency 3. Письма в critical. Запись одним запросом на пачку:

DB[:products]
  .insert_conflict(
    target: :sku,
    update: { price: Sequel[:excluded][:price], updated_at: Sequel::CURRENT_TIMESTAMP }
  )
  .multi_insert(rows)

Итог первой ночи: импорт закончился в 3:10, раньше тянулся до девяти утра, очередь писем ни разу не поднималась выше 20. Утром впервые за месяц никто не написал в поддержку, что письмо не пришло.


Ответ
armen_pet
Сообщения: 30
Собрал свой gem DevOps-инженер
Присоединился: 4 года назад

И повесьте алерт не только на размер очереди, но и на возраст самой старой джобы. Sidekiq это отдаёт: Sidekiq::Queue.new("critical").latency. Если latency писем больше минуты, пусть кто-то узнаёт об этом раньше пользователей.


Ответ
1 ответ
eldar14
Присоединился: 4 года назад

Дружит с bundler middle-разработчик
Сообщения: 9

завидую, в Resque latency из коробки нет, считаем сами по времени постановки


Ответ