Railsでアプリケーションを作っていると非同期処理でSidekiqを使用することが多いと思います。今回はSidekiqを使用する際の注意点について記載していきます。
具体的には
- リトライ
- サーバプロセスが落ちると、jobのデータは失われる
- メモリ肥大化する問題
- 並列実行数制御
について記載します。
Sidekiqを正しく理解して安全に使おう!という記事になります。
まずはSidekiqとは?について記載していきます。
Sidekiqとは
Railsで非同期処理を行うためのgemです。複数の非同期処理を同時に実行することができ、サーバリソースを有効活用できます。
以下、処理イメージです。
- Rails WEBサーバがリクエストを受け付ける
- Rails WEBサーバは非同期でしたい処理をRedisにjobとして格納する
- Sidekiqが動いているサーバがRedisからjobを取得する
- Sidekiqはjobの内容にしたがって処理を実行する
AWS SQSと連携させて、非同期処理を行うShoryukenというgemもあります。
[注意点①]プログラムで例外発生時は、リトライされる
デフォルトのリトライの仕様は以下の通りとなります。約21日間リトライが行われます。
リトライ回数:25回
リトライの間隔:リトライ回数の4乗+15秒間隔くらい。正確な計算式は以下の通り
(retry_count ** 4) + 15 + (rand(10) * (retry_count + 1))
リトライで解消する可能性がある場合は、リトライは有効かと思いますが、何度リトライしても失敗するようなエラーの場合はサーバ負荷をかけるだけなので、リトライさせないようにしておくと良さそうです。
リトライ回数をデフォルトから変更するなど、リトライ時の処理を設計して実装しておきましょ!
[注意点②]サーバプロセスが落ちると、jobのデータは失われる
サーバプロセスが落ちると、jobのデータは失われてしまいます。
Sidekiq Pro(Sidekiqの有料版)のsuper_fetchを使用すると、サーバプロセスが落ちてもjobデータが失われなくなりますので、Sidekiq Proを検討しましょ
または、Sidekiqをやめて、Shoryukenの検討をしましょ。
ShoryukenではSQSを使用しますが、サーバプロセスが落ちてもSQSのデータ失われないためです。
[注意点③]メモリ肥大化する問題
大量のメモリを消費する問題があります。
メモリの問題に関しては、以下の記事を参考に設定を変更して対応しましょ
[注意点④]並列実行数制御
大量に同時実行するとインフラ負荷がかかりすぎる場合、並列実行数制御をしましょ!
インフラ負荷とは以下のようなイメージでいます。
- 大量に同時実行すると
- Sidekiqが動いているサーバに負荷がかかる
- DBに負荷がかかる
並列実行数制御にはsidekiq-limit_fetchというgemを使います。
注意点として、Sidekiq Proを使用している場合、sidekiq-limit_fetchは正常に動作しないので要注意です。
Sidekiq Proを使用している場合は
- Sidekiq Enterpriseの導入を検討する
- 自分で並列実行数を制御するプログラムを作成する
- 以下のようなイメージです
- 「Sidekiq::Workers.new」で実行中のjobを取得し、並列実行数をチェックする
- 並列実行数をチェックした結果、処理実行して良い場合、そのまま処理実行
- 並列実行数をチェックした結果、並列実行の上限を超えている場合、「perform_later」でjobをredisに戻し、処理を終了する
- 「Sidekiq::Workers.new」で実行中のjobを取得し、並列実行数をチェックする
- 以下のようなイメージです
まとめ
Sidekiqを使用する際の注意点について記載しました。
まとめると
- リトライ
- リトライ回数を意識して設計しましょ
- サーバプロセスが落ちると、jobのデータは失われる
- Sidekiq Proを検討しましょ
- メモリ肥大化する問題
- メモリに関する設定を見直しましょ
ということです★