sidekiqのソースを読んでみた
- sidekiqを使ってるけどなかってどうなってるの?というのを調べることがあったのでまとめ
前提
- バージョン
- v5.2.5
- 読んでみたタイミング
- 2019/03
- ここで書かないこと
- siekiqの使い方
- Thread周り
- 基本的なとこだけ読んでます
- 読んでみたなので正確ではないこともあります。。
クライアント側(jobを積むほう)
Sidekiq::Worker
- 実行する処理とかを用意するクラスにincludeするモジュール
- includeしたクラスにperform_asyncとかが特異メソッドとして追加される
#perform_async
- 中でSidekiq::Clientのオブジェクトを生成してpushを読んでる
Sidekiq::Client
- redisにjobをつむところの役割をやってる
#push
- workerに渡す引数+jobのidを用意して整形してatomic_pushに投げる
#atomic_push
- redisのqueuesていうキーにつむjobのキュー名を入れている(タイプがsetなので同じものを入れるときは重複しない)
- redisのqueue:キュー名のキーにjobを追加する
サーバー側
- jobを実行するほう
登場するクラス
-
Sidekiq::CLI
- サーバー側の起動を行う
- そのあとは停止などのコマンドを受け付ける
-
Sidekiq::Launcher
- このオブジェクトのrunを呼べばサーバー側が動く
- jobを取ってきて処理するのと、retryやスケジュールからqueueを積む処理を起動してくれるのでランチャー
-
Sidekiq::Manager
- Sidekiq::Processorを作成&ぐるぐる実行させる
-
Sidekiq::Processor
- 一定時間ごとにqueueをチェックしに行って処理を実行
- こいつがperformを呼び出してる
-
Scheduled::Poller
- 即時実行じゃないjobや一度失敗したjpbを確認して、実行タイミングになったらqueueに積む
sidekiq起動のところ
bin/sidekiq
- Sidekiq::CLI.instance
- Sidekiq::CLIのインスタンスを生成(instanceってなんだ?と思ったけどシングルトンだった。。)
- Sidekiq::CLI#parse
- 設定とかをsetしてる
- Sidekiq::CLI#run
- Sidekiq::Launcherのインスタンスを生成&Sidekiq::Launcher#runを呼び出したあとはコマンドを受け付けるためぐるぐるし続ける。
- Sidekiq::Launcher#run
- Sidekiq::Manager#startとSidekiq::Scheduled::Poller#startを呼び出す
- Sidekiq::Manager#start
- Sidekiq::Processor#startを呼び出す
- Sidekiq::Processor#start
- スレッドでrunを実行
- Sidekiq::Processor#run
- jobがあればとってきて該当workerのperformを実行をぐるぐる。
- Sidekiq::Processor#run
- スレッドでrunを実行
- Sidekiq::Processor#start
- Sidekiq::Processor#startを呼び出す
- Sidekiq::Scheduled::Poller#start
- redisのretryとscheduleの中で実行タイミングになったものを取り出してqueueにつむ。
- retryとscheduleはzsetで、timestampをキーにしてて、今の時間よりも小さいものーでとってるっぽい
- redisのretryとscheduleの中で実行タイミングになったものを取り出してqueueにつむ。
ざっくりかくと
Sidekiq::CLI -> Sidekiq::Launcherを叩いてあとは入力待ちぐるぐる
Sidekiq::Launcher#run -> Sidekiq::Manager#startとSidekiq::Scheduled::Poller#startを叩く
Sidekiq::Manager#start -> Sidekiq::Processorをぐるぐるさせる
Sidekiq::Scheduled::Poller -> ぐるぐる
おまけでRedisに登録されるもの
※ namespaceは省く
|キー | type | 値 |
|---|---|---|----|
|schedule | zset | 予定されたジョブが入っている |
| queues | set | 一度でもジョブが積まれたキューのリスト |
| stat:processed | string | 完了したジョブの数 |
| stat:processed:yyyy-mm-dd | string | 該当日に完了したジョブの数 |
| stat:failed | string | 失敗したジョブの数 |
| stat:failed:yyyy-mm-dd | string | 該当日に失敗したジョブの数 |
| queue:キュー名 | list | そのキューの待機状態のジョブのリスト |
| limit:processes | set | TODO (limit:heartbeatのUUIDが入っていた。。) |
| limit: heartbeat:UUID | string | TODO (trueとか入ってる。。) |
| host:port:xxxx:workers | hash | そのworkerが現在実行中のジョブの情報 |
感想
- ランチャーってなんぞと思ったけど、一括で必要なのを起動してくれるもののことらしいと今回知った。。
- Threadとか詳しくないのでいつかちゃんと触って理解しよう。。
- redisの型とか全然知らなかったのでちょっと知れてよかった。
- gemを読んでみたって記事はありなのか。。?(お勉強メモなのでお許しください。。)
- 顔文字とか絵文字のメソッドがちょいちょいあって面白かった