ご機嫌よう、ガラパゴスのおとめです。
突然ですがRailsをお使いの皆さんは非同期処理にSidekiqを使ったりしていると思います。それで普通にデプロイするとSidekiqは1プロセスになりますね? 今回はかあるく短く、Sidekiqプロセスを複数にしたいなあ、というお話をしようと思います。
都合によりちょっと記事中のバージョンが古いですがご了承くださいね。
どうして複数プロセスにしたいの?
アプリケーションサーバーも非同期処理も全部一台で動かしているならSidekiqは1プロセスでもいいですが、多くの場合はサーバーを分けたりしているかと思います。
ところで、今時のサーバーならマルチコアですね? でも、1プロセスで動かしている限り、1コアしか使われません。当然ながら他の資源は無駄になります。
また、Rubyのマルチスレッドモデルでは、ブロッキングIOが発生しない限りコンテキストが切り替わりませんので、一つのワーカーで計算ばかり重い処理をしていると、他のワーカーが動かないといったことも起こります。
いやん。
もちろんコンテナで動かすとか資源を有効に活用する方法は他にもあるのですが、ここではとりあえず簡単にすぐにできる方法を試してみましょう。
複数のSidekiqを起動してみる
では、試しに複数起動しちゃってみましょう。必要な設定とかは書いてあるとして。
$ bundle exec sidekiq -C config/sidekiq.yml -L log/sidekiq1.log -d $ bundle exec sidekiq -C config/sidekiq.yml -L log/sidekiq2.log -d
するとこのように、無事に複数起動するかと思います。
$ ps aux | grep sidekiq otome 2383 0.0 0.0 4277992 908 s001 S+ 9:09AM 0:00.00 grep sidekiq otome 2377 0.0 1.2 4546588 204840 ?? S 9:09AM 0:09.43 sidekiq 4.0.2 sidekiq-test [0 of 10 busy] otome 2109 0.0 1.8 4659228 296080 ?? S 9:09AM 0:13.17 sidekiq 4.0.2 sidekiq-test [0 of 10 busy]
もちろん、設定ファイルを分けることで、プロセスによって処理するキューを分けたりワーカー数を変更したりすることもできます。
例えば一方のプロセスで foo
キューを処理して、
:pidfile: ./tmp/pids/sidekiq1.pid :logfile: ./log/sidekiq1.log :queues: - foo
別のプロセスで bar
キューを処理するとします。
:pidfile: ./tmp/pids/sidekiq2.pid :logfile: ./log/sidekiq2.log :queues: - bar
あとはこれを引数に与えるだけですね。
どうやってデプロイするのん?
さて、では本番的な環境に適用しましょう。
大抵の場合はRailsアプリケーションのデプロイにはcapistranoを使われているかと思います。Sidekiqのデプロイにはcapistrano-sidekiqをお使いでしょう。
READMEを眺めてみると「なるほど???」という感じもしますが、例えば以下のようにすることで、複数のプロセスを異なる設定ファイルで起動することができます。
set :sidekiq_processes, 2 set :sidekiq_options_per_process, [ "--logfile #{release_path}/log/sidekiq1.log --config #{release_path}/config/sidekiq1.yml", "--logfile #{release_path}/log/sidekiq2.log --config #{release_path}/config/sidekiq2.yml" ]
もちろんconfigに与える設定ファイルを同じにすれば、同じ設定ファイルで動きます。
早速デプロイしてみると、無事にSidekiqプロセスが複数になっているかと思います。
ところでガラパゴスではエンジニアを募集しています。ご興味をお持ちの方はぜひ弊社の採用ページをご覧ください。
では、ご機嫌よう。
--
この記事は業務の一環として業務時間中に書きました。