Sidekiqの高度なオプション
最終更新 2019/09/03 編集者 Mike Perham
Sidekiqの設定ファイル
Sidekiqの設定ファイルはYAML形式です。デフォルトの場所は config/sidekiq.yml
になります。
高度なオプションを利用する場合のみ、設定ファイルを作る必要があります。高度なオプションとは、コンカレンシーサイズ、名前付きキュー、PIDファイルの場所指定などです。
設定ファイルの記載例は下記の通りです。
:concurrency: 5
staging:
:concurrency: 10
production:
:concurrency: 20
:queues:
- critical
- default
- low
設定ファイルの場所を明示的に指定する場合は -C
フラグを使用してください。
sidekiq -C config/myapp_sidekiq.yml
コマンドラインで指定されたオプションは設定ファイルの内容を上書きします。
キュー
デフォルトの状態では、Sidekiqは default と名前の付いた単一のキューのみを使用します。
複数のキューを利用したい場合は、sidekiq
コマンドの引数として指定するか、設定ファイルに記載することができます。
それぞれのキューには重みを設定することができます。重みとして 2 が設定されているキューは、1 が設定されているキューと比較して2倍の頻度でチェックされます。
引数でキューの名前と重みを指定する場合:
sidekiq -q critical,2 -q default
上記と同じ内容を設定ファイルで指定する場合:
# ...
:queues:
- [critical, 2]
- default
常にキューを指定した順番通りに処理してほしい場合は、重みなしで処理してほしい順番通りに設定ファイルを記載してください。
引数で処理する順番通りにキューを指定する場合:
sidekiq -q critical -q default -q low
上記と同じ内容を設定ファイルで指定する場合:
# ...
:queues:
- critical
- default
- low
上記の通りに記載すると、defaultキューのジョブはcriticalキューが空の時のみ処理されます。
それぞれのキューのジョブをランダムな順番で処理してほしい場合は、重みを 1 に設定してください。そうすることでそれぞれのキューが均等に処理されるようになります。
# ...
:queues:
- ["foo", 1]
- ["bar", 1]
- ["xyzzy", 1]
ワーカーが使うキューはワーカークラスの中で指定することができます。
class ImportantWorker
include Sidekiq::Worker
sidekiq_options queue: 'critical'
def perform(*important_args)
puts "Doing critical work"
end
end
キューの数は少数にとどめてください。たくさんのキューはシステムをより複雑にしますし、Sidekiq Proはポーリングなしで複数のキューを確実に処理することができません。
M個のSidekiq ProプロセスがN個のキューをポーリングする時、Redisに対してO(M*N)の操作が発生すること(これは非常に多い)を意味します。
SidekiqのWeb UIでは、もっとも新しく追加されたキュー(のジョブ)が一番上に表示されます。
キューを予約しておく
特定のジョブだけを処理するキューをあらかじめ用意しておきたい場合、これをもっとも簡単に実現するには、異なるキューを処理する複数のSidekiqプロセスを実行してください。
sidekiq -q critical # criticalキューのジョブのみを処理する
sidekiq -q default -q low # それ以外のジョブを処理する
ワーカー
Sideiqにはワーカーの振る舞いを制御するたくさんのオプションがあります。
- queue ワーカーが利用するキューの名前を指定する。デフォルトの値は default
- retry RetryJobsミドルウェアを有効にする。デフォルトの値は true 真偽値ではなく数字を与えると再試行する回数を指定することもできます。例:retry: 3
- backtrace 例外のバックトレースを保存しておくかどうか。保存されたバックトレースはWeb UIの再試行タブで見ることができます。真偽値または保存する行数を数字で指定することができます。デフォルトの値は false です。バックトレースはRedis上で非常に多くのスペースを使うため、再試行するジョブが多くなる場合は注意して扱ってください。
- pool Redisへジョブをプッシュする際に利用するコネクション数
class HardWorker
include Sidekiq::Worker
sidekiq_options queue: :crawler, retry: false, backtrace: true
def perform(name, count)
end
end
デフォルトのオプションをワーカーに指定する場合は Sidekiq.default_worker_options=
が利用できます。
Sidekiq.default_worker_options = { 'backtrace' => true }
ワーカーに指定されたオプションはジョブのプッシュの際に上書きすることができます。
HardWorker.set(queue: :critical).perform_async(name, count)
同時実行制御
Sidekiqプロセスの同時実行スレッド数を指定することができます。デフォルトでは、1つのSidekiqプロセスは10個のスレッド を作成します。
I/Oに関係するクラッシュが起きる場合は、この数字を減らすことができます。
bundle exec sidekiq -c 5
RAILS_MAX_THREADS=3 bundle exec sidekiq
コンカレンシーを50よりも大きくすることは非推奨です。Rails 5から、RAILS_MAX_THREADS
でRailsとSidekiqのコンカレンシーを設定することができます。
ActiveRecordは config/database.yml
でデータベースへ接続する際のコネクションプール数を指定することができます。この数はスレッド数と同じになるようにしてください。
コネクションプール
Sidekiqはconnection_pool gemを同封しており、ワーカーから利用することができます。
コネクションプールを利用することで、たくさんのスレッドが動く環境であっても、I/Oコネクションの数を制限することができるようになります。
class HardWorker
include Sidekiq::Worker
MEMCACHED_POOL = ConnectionPool.new(size: 10, timeout: 3) { Dalli::Client.new }
def perform(args)
MEMCACHED_POOL.with do |dalli|
dalli.set('foo', 'bar')
end
end
end
上記のようにすることで、このワーカーの同時実行数が多くなったとしても、Sidekiqプロセスからmemcachedへ接続するコネクション数を常に10個に限定することができます。