Help us understand the problem. What is going on with this article?

Sidekiq 6の新機能・変更点

はじめに

Ruby on Rails (以下Rails) でバックグラウンドジョブを実行する際によく使用されるGemである、Sidekiqのバージョン6.0が今年(2019年)9月にリリースされました。このバージョンでは、Active Jobへのオプション指定などの機能強化と共に、パフォーマンス向上が行われ、sidekiqctlコマンドが廃止されるなどの大きな変更が行われています。本記事では実際に使用した経験を元に、Sidekiq 6の新機能や変更点について説明を行います。

注意点

本記事で取り扱うエディション

本記事ではGitHubで公開しているOSS版のSidekiqについて記述しています。Pro / Enterprise版を使用している場合は、公式サイト(英語)を参考にしてください。

サポートされるRails / Ruby / Redisのバージョン

サポートされるバージョンは以下の通りになります。

  • Ruby on Rails 5以上
  • Ruby 2.5以上
  • Redis 4以上

上記より古いバージョンを使用している場合は、アップグレードを事前に行う必要があります。

新機能

Active JobでSidekiq独自のオプションを指定可能に

ActiveJob::Baseを継承したジョブで使用する際に、sidekiq_optionsを指定することで、Sidekiq独自のオプションを一部使用できるようになりました。

以下はリトライの回数と、Web UIで表示するバックトレースの行数をsidekiq_optionsで指定しています。

class MyJob < ActiveJob::Base
  queue_as :myqueue
  sidekiq_options retry: 10, backtrace: 20
  def perform(...)
  end
end

以下が使用できるオプションの一覧となります。

オプション 内容
retry 整数 リトライ回数を指定する
backtrace true, false, 整数 SidekiqのWeb UIにバックトレースを表示するかどうか
整数の場合は指定した行数で表示する

参考

ログの出力形式を選択可能に

ログの出力機能がプラグイン化され、出力形式を選択できるようになりました。例えば、JSON形式の出力を行う場合は、以下のようにSidekiq::Logger::Formatters::JSONを指定します。

Sidekiq.configure_server do |config|
  config.log_formatter = Sidekiq::Logger::Formatters::JSON.new
end

以下が使用できるログの出力形式の一覧となります。

フォーマッタ 説明
Sidekiq::Logger::Formatters::Pretty 通常の出力
Sidekiq::Logger::Formatters::WithoutTimestamp タイムスタンプなしで出力
Sidekiq::Logger::Formatters::JSON JSON形式で出力

ログ出力の例

Sidekiq::Logger::Formatters::Pretty

2019-08-31T15:36:07.569Z pid=82859 tid=11cy9br class=HardWorker jid=528f1b0ddc4a9d0690464fe4 INFO: start

Sidekiq::Logger::Formatters::WithoutTimestamp

pid=82859 tid=119pz7z class=HardWorker jid=b7f805c545c78770d30dc1fd elapsed=0.089 INFO: done

`Sidekiq::Logger::Formatters::JSON

{"ts":"2019-09-01T22:34:59.778Z","pid":90069,"tid":"104v8ph","lvl":"INFO","msg":"Running in ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]"}

参考

ジョブ毎のログレベル指定が可能に

ワーカーの.setメソッドの引数でlog_levelを指定することで、特定のジョブのログの出力レベルを指定できるようになりました。

MyWorker.set(log_level: :debug).perform_async(...)

SidekiqはデフォルトでRubyの標準ライブラリのLoggerを使用しており、log_levelで指定できるのは、:unknown:fatal:warn:info:debugになります。

参考

ジョブのタグ付けが可能に

ワーカーのクラスのsidekiq_optionstagsを指定することで、ジョブのタグ付けができるようになりました。

class MyWorker
  include Sidekiq::Worker
  sidekiq_options tags: ['bank-ops', 'alpha']
  ...
end

参考

Web UIでのダークモードのサポート

ダークモードがサポートされたブラウザ(IEやEdge、Operaは非サポート)でモードが有効な状態でWeb UI(Sidekiqの管理画面)にアクセスした場合は、黒ベースの画面で表示するようになりました。

参考

変更点

sidekiqctlコマンドの削除

Sidekiqプロセスを停止、終了するために用いられてきた、sidekiqctlコマンドが廃止されました。Sidekiq 6では、このコマンドの代わりにkillコマンドでシグナルを送ることで、プロセスの停止、終了を行うことができます。

廃止されたコマンド 代替となるコマンド 説明
sidekiqctl quiet kill -TSTP <pid> ワーカーの各スレッドを停止
sidekiqctl stop kill -TERM <pid> (上記コマンドの実行後に)プロセスを終了

デーモン化を廃止し、サービスとして実行するように

サービスの管理をOS側(Systemd、Upstartなど)で行うようにするために、デーモン化を廃止しました。このため、本番環境などサーバーで動かす場合は、Sidekiqのサービスの設定ファイルを新たに作成し、サービスを有効にする必要があります。 

デーモン化の廃止に至った背景に関しては、Sidekiq作者による説明が以下のページにあります。

上記の記事では、以前から使用されてきた長時間動作するデーモンプロセスが、現在ではSystemdを使用したサービスに置き換えられていて、このことによって、ロギングやクラッシュ時の再実行などの処理を自前で実装することがなく、より堅牢な実行が可能になった、ということが書かれています。

Sidekiqのサービスの設定、起動や停止コマンドに関しては、この記事の次の節のアップグレードの部分を参考にしてください。

logfilepidfileコマンド引数の廃止 

上記のデーモン化の廃止に伴って、ログの出力や、プロセスIDの保持をSystemdなどのサービス側で行うようになったので、sidekiqコマンドからlogfilepidfileコマンド引数が削除されました。 

デフォルトのシャットダウン時間が8秒から25秒に変更に

HerokuのDynoとAmazon ECS コンテナがアプリケーションのシャットダウンで30秒のタイムアウトを使用するようになったため、Sidekiqも8秒から25秒にタイムアウト時間を伸ばしました。以前の挙動に戻すには、オプション-t 8sidekiqコマンドに対して指定します。

REDIS_PROVIDER環境変数の検証を行うように

REDIS_PROVIDER環境変数は、RedisサーバーのURLを保持する他の環境変数を指定するのに使用します。もし、REDIS_PROVIDER変数に直接URLなどの不適切な文字列が指定されている場合は、以下のような警告を出すようになりました。

REDIS_PROVIDER should be set to the name of the variable which contains the Redis URL, not a URL itself.
Platforms like Heroku will sell addons that publish a *_URL variable.  You need to tell Sidekiq with REDIS_PROVIDER, e.g.:

参考

パフォーマンスの向上

生成するオブジェクトを減らすなど、細かいコードのチューニングを行うことによって、Sidekiq 5系列と比較して、10-15%実行速度が向上しているそうです。

参考

アップグレード方法

Gemのアップグレード

最初に、Gemfileに以下のように指定して、bundle updateを実行して、Sidekiq 5系列の最新版にアップグレードします。

gem 'sidekiq', '< 6'

Sidekiqを動かしてみて、非推奨の警告(Deprecation warnings)が出ないようにコードの修正を行います。

修正が完了したら、Gemfileに以下のように指定して、再度bundle updateを実行して、Sidekiq 6.xへアップグレードします。

gem 'sidekiq', '< 7'

サービスの設定ファイルの作成

変更点で述べたように、本番環境では、Sidekiqプロセスはデーモンでなくサービスとして起動するようになったため、設定ファイルを作成する必要があります。

開発環境では、これまで通りユーザーがsidekiqコマンドを実行してフォアグラウンドで起動し、ログは標準出力および標準エラー出力に送信されるため、サービスとして起動させる必要はありません。

SystemdでSidekiqをサービスとして実行するには、以下のファイルを元に設定ファイルを生成し、サーバーの適切な場所(CentOSの場合は/usr/lib/systemd/system、Ubuntuの場合は/lib/systemd/system)に配置する必要があります。

https://raw.githubusercontent.com/mperham/sidekiq/master/examples/systemd/sidekiq.service

例えばrbenvのbundlerを使用していて、アプリケーションのディレクトリが/var/www/myapp/currentの場合は、以下のように変更する必要があります。

WorkingDirectory=/var/www/myapp/current
...
ExecStart=/usr/local/rbenv/shims/bundle exec sidekiq -e production

ファイルの配置を行ったら、以下のコマンドでサービスを有効にします。

$ sudo systemctl enable sidekiq

サービスの起動と停止

設定ファイルを配置後は、以下のコマンドでサービスの起動と停止を行います。

サーバーの起動

$ sudo systemctl start sidekiq

サーバーの停止

$ sudo systemctl stop sidekiq

参考URL

ryohashimoto
A software engineer in Tokyo. Ruby on Rails contributor. React、Go、Elasticsearchを使ったWebサービスの開発をやっています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした