7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Sidekiqのベストプラクティス [翻訳]

Last updated at Posted at 2019-09-12

Sidekiqのベストプラクティス

最終更新 2019/04/27 編集者 Madogiwa

Sidekiqのパフォーマンスを改善するには、次のルールに従ってください。

1. ジョブ引数を小さくシンプルにする

Sidekiqは、perform_async の引数をJSONとしてRedisに保存します。私はこのようなコードをたくさん見かけます。

quote = Quote.find(quote_id)
SomeWorker.perform_async(quote)

複雑なRubyオブジェクトはJSONに変換することができません。デフォルトでは to_s を使って変換することになり、その結果は #<Quote:0x0000000006e57288> のようになります。

たとえシリアライズができたとしても、キューに保存されている間に quoteオブジェクトの値が変更されたらどうなるでしょうか? 状態をSidekiqに保存するのではなく、シンプルなIDを保存するようにしてください。 そして、performメソッド内で実際に必要になったタイミングで、オブジェクトをfindするようにしてください。

SomeWorker.perform_async(quote_id)

perform_async メソッドに渡す引数は、 文字列、整数、浮動小数点、真偽値、null(nil)、配列、ハッシュ といったシンプルなJSONデータ型で 構成する必要があります 。これは、Rubyのシンボルを引数に 使用してはいけない ということを意味します。

SidekiqクライアントAPIはRedisへデータを送信するために JSON.dump を使用します。Sidekiqサーバーは、そのJSONデータをRedisからプルし、 JSON.load を使ってRubyオブジェクトに戻し、performメソッドに渡します。

シンボル、名前付きパラメーター、複雑なRubyオブジェクト(DateやTimeなど!)を perform_async メソッドに渡さないでください。 これらの値またはオブジェクトは、dump/loadの変換で正しく渡される保証がありません。

2. ジョブを冪等にし、トランザクションを利用する

冪等性とは、ジョブを複数回安全に実行できる性質のことです。例えば、エラーが起きた際のリトライの仕組みが用意されているとき、ジョブが半分だけ実行されて、そこで例外が起きて、正常に完了するまで何度も再実行されることがあります。

さらに具体的な例として、クレジットカードの取引を無効にし、請求金額の払い戻しがあることをユーザーにemailで知らせるジョブがあるとします。

def perform(card_charge_id)
  charge = CardCharge.find(card_charge_id)
  charge.void_transaction
  Emailer.charge_refunded(charge).deliver
end

emailの送信がバグで失敗した時に何が起きるでしょうか? void_transaction メソッドは、請求金額が既に返金済みのケースを正しく処理できるでしょうか? このような疑問を解消するためには、次の2つの方法が利用できます。

  • 1つめは、エラーが起きたときにデータベースへの変更を正しくロールバックするようトランザクションを使うという方法。
  • 2つめは、エラーが起きたときにそのエラーを適切に処理するような弾力性のあるコードを書くという方法です。

Sidekiqは、ジョブを 必ず1回 ではなく、 少なくとも1回 実行するという点を忘れないでください。

3. 並行性を取り入れる

Sidekiqは並列実行向けにデザインされています。そのため、ジョブを並列実行可能に設計すれば、Sidekiqのパフォーマンス上の恩恵を最大限受けることができるようになります。

Sidekiqは並行性を調整するための基本的な機能を持っています。例えば、1つのキューを処理するスレッドの数を事前に定義する機能などです。but your system architecture is much simpler if you don't have such specialization.

Sidekiqプロセスからのトラフィックが他のサーバーを圧迫しているのであれば、全体の接続数を制限するためにコネクションプールを利用することができます。

Sidekiqはジョブの中で並行性を調整するような機能は提供していません。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?