Статьи

Сравнение библиотек фоновой обработки: Sidekiq

Люди и дверь синие

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

  • Принципы фоновой обработки (очереди, процессы и т. Д.).
  • Используя delayed_job, который удивителен для быстрой фоновой обработки в вашем приложении, но он использует ActiveRecord, поэтому он довольно медленный, и вы в конечном итоге смешиваете фоновый и основной код во всем приложении.
  • Использование Resque, которое надеется решить проблемы с delayed_job с помощью Redis и отдельных рабочих классов.

Тем не менее, мы все еще можем улучшить производительность Resque. Это где Sidekiq входит.

Sidekiq

Если вы прочитали раздел теории в предыдущих статьях (что вам действительно нужно), вы, возможно, заметили, что я говорил о процессах как о единственном варианте параллелизма. Оказывается, это не совсем так, и Sidekiq в полной мере использует кое-что еще: потоки.

Потоки — это сверхлегкая мера параллелизма для повышения производительности. Заголовок на странице Sidekiq гласит

«Что если один процесс Sidekiq может выполнить работу 20 процессов Resque или DelayedJob?»

Давайте посмотрим, как использовать Sidekiq. Если вы прочитаете введение в delayed_job и Resque, Sidekiq — это комбинация двух. Sidekiq использует Redis, так что вам нужно будет установить и запустить его (посмотрите раздел Resque в предыдущих статьях, чтобы узнать, как это сделать).

Чтобы начать, добавьте следующую строку в ваш Gemfile:

gem 'sidekiq' 

Установить ‘up:

 bundle install 

К счастью, это все, что нам нужно для настройки. SideKiq не использует систему граблей напрямую, как Resque, поэтому нам не нужно возиться с «lib / tasks». Давайте перейдем к написанию нашего работника печати в «app / worker / print_worker.rb». Вот:

 class PrintWorker include Sidekiq::Worker def perform(str) puts str end end 

Еще раз, мы должны где-то поставить в очередь работу (мы сделаем это в контроллере индекса):

 class IndexController < ApplicationController def index PrintWorker.perform_async(params[:to_print]) end end 

Наконец, мы должны запустить процесс (ы) Sidekiq. Введите это в свою оболочку в корневом каталоге вашего приложения Rails:

 bundle exec sidekiq 

Это запускает процесс, который ждет работы. Давайте поставим один в очередь.

Если вы перейдете к «/ index / index? To_print = sidekiqisgreat», вы должны получить «sidekiqisgreat» где-нибудь в выходных данных вашего процесса sidekiq (бегунок sidekiq содержит некоторую другую информацию, которую вы можете смело игнорировать в качестве примера.)

Sidekiq достаточно прост, если вы изучили Resque, но у него есть довольно большая «проблема», которую мы еще не обсуждали: безопасность потоков. Поскольку Sidekiq использует потоки, вы можете использовать библиотеки в Sidekiq только в том случае, если они потокобезопасны — все остальное, вероятно, вызовет массу проблем, которые трудно отследить. Это действительно ограничивает то, что вы можете сделать с Sidekiq.

Во-вторых, вы должны убедиться, что ваш код потокобезопасен (например, глобальные переменные запрещены). Ruby (точнее, интерпретатор ruby ​​«по умолчанию», то есть MRI) также имеет то, что называется «блокировкой интерпретатора», что означает, что одновременно может работать только один поток, поэтому Sidekiq будет работать намного лучше с альтернативными реализациями Ruby, такими как Рубин и JRuby.

Какой смысл преодолевать все эти хлопоты? Почему бы просто не использовать Resque? Самая большая причина — производительность; разница довольно велика, если вы обрабатываете много заданий, которые выиграют от параллелизма.

Финальное сравнение

В этой серии из трех частей мы рассмотрели теорию фоновой обработки и три среды фоновой обработки: delayed_job, Resque и Sidekiq. У каждого есть свои взлеты и падения.

С задержкой: работа:
* Плюсы
невероятно быстро и легко катиться
— без добавления в ваш «стек»; он может нормально работать с ActiveRecord
— фантастический выбор для начинающих или перенос кода с переднего плана на задний план
* Минусы
— Работает на ActiveRecord, поэтому он, вероятно, будет работать медленнее, чем то, что работает на Redis
— Очень легко смешивать асинхронный и синхронизирующий код в файле, что, на мой взгляд, плохо
— Вызовы «.delay», разбросанные по вашей базе кода, затруднят рассуждение примерно через шесть месяцев

С Resque:
* Плюсы
— Он работает на Redis, который быстро
— Отличное разделение фонового кода с рабочими классами
У него фантастическая веб-панель
— Это довольно легко сделать фоновую обработку
— Это мой любимый!
* Минусы
— Сложнее запустить с задержкой, чем с задержкой
— Все еще не самый быстрый!
— Выполнение приоритетных, основанных на времени заданий не так просто, как delayed_job

С Sidekiq:
* Плюсы
— чертовски быстро и рабочие легкие
— Вы можете легко переносить код из Resque
— Отличное разделение кода
* Минусы
— сложнее, чем delayed_job
— (это важная персона) Вы должны использовать многопоточные библиотеки и писать поточно-безопасный код

Как я уже упоминал, мне больше всего нравится Resque из трех. Моя основная причина избегать delayed_job — это смешивание кода синхронизации и асинхронного кода. При рассмотрении Sidekiq меня пугает требование многопоточных библиотек.

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

Пример приложения

Я создал небольшой пример приложения с использованием Sidekiq. Он выполняет те же действия, что и примеры delayed_job и Resque, но с использованием Sidekiq. Он сохраняет и отображает количество страниц в загруженном PDF-файле синхронно и асинхронно. Самое важное, что нужно отметить, — это то, что мне пришлось изменить примерно три строки кода, чтобы переключиться с Resque на Sidekiq, потому что библиотека, которую я использовал для подсчета страниц в PDF, оказалась поточно-ориентированной . Однако, если бы это было не так, написание порта Sidekiq было бы намного сложнее, поскольку мне пришлось бы либо свернуть свою собственную библиотеку, либо использовать расширение C.

Код для примера приложения можно найти здесь .

Завершение

Как вы можете сказать, сообщество Ruby представило три уникальных решения одной проблемы. У каждого есть свои преимущества и недостатки. Выберите тот, который вам нравится больше всего, и используйте его в своем следующем удивительном приложении!

Если у вас есть какие-либо вопросы или предложения, пишите в комментариях ниже!