-- Views
June 02, 26
スライド概要
こんにちは、小早川秀秋です
関ケ原Ruby会議01での登壇資料です
Job戦国時代 紅玉宿禰木下赤羽守ppyd翔央 @ 青色人労
やあやあ、遠からん者は音にも聞け、 近くば寄って目にも見よ。 我こそは、父を筑前国に持ち、母を 河内国に仰ぎ、河内の地に生を享け、 幼き日を武蔵国にて過ごせし者。 幼少の砌より紅玉の武に身を投じ、 ついには暗黒の位を賜りし者なり。 今は蒼色人労の地にて武の道を磨き、 近頃は微小紅玉の術理を究めんと、 新たなる技の研鑽に励むものなり。
世は
Job戦国時代 [要出典]
2つの陣営が
関ケ原で激突する!
🤗
SolidQueue vs Sidekiq •簡易的なベンチマークは世の中に溢れている •だが、実際の業務で使うようなJobでのベンチマークは少ない •現実のユースケースではどうなのか……俺バカだからやってみない とわかんねえ
Job in Real World? •SidekiqのWikiなどで指標に使われるのは、no-opなJob •現実では、当然ながらCPUとIOを使う •秒間に数百のJobが積まれていくと、レイテンシはどうなるのか?
Benchmark •Jobは、IO bound、CPU bound、両 使うの3種を 意 •RailsアプリにPOSTすると、Jobがエンキューする構成 用 方 •エンキュー前にJobオブジェクトを保存しておき、後から集計する
CPU / IO bound •CPU boundはBcryptを使ってパスワードのハッシュ化 •IO boundはHTTPリクエストを送信して結果を待つ •現実ではおそらく CPU < IO ではないかなと思う
Metrics •エンキューから開始までのレイテンシ •開始から完了までのレイテンシ . を 見 5 9 、p 9 9 、p 9 0 、p 9 0 5 •リクエスト数変えながら p てみる
Strategy •k を使い、1分間ウォームアップしながら100/sのリクエスト6分間 •統計 のJobオブジェクトを作成時間基準で10秒フレームに分類 9 9 用 6 •各フレームp で1秒以下のレイテンシをクリアすれば、追加100/s
Parameters •VMのCPUコア数 2/4/8 •SolidQueue/Sidekiq のプロセス数 1-10 •SolidQueue/Sidekiqのスレッド数 3-15
Application •sekigahara(https://github.com/kufu/sekigahara) •JobをキックするEast(worker_ignitor)と、Jobからリクエストを 受けるWest(hook_receiver) 一 •起動時の環境変数で、SolidQueueとSidekiqを切り替えられるよう にしたので、単 のコンテナで試験可能
fi con g/application.rb
fi con g/routes.rb
bin/job
app/controllers/job_conntroller.rb
Environment •Google Cloud •Webアプリは 量のCloudRun、DBはPostgreSQLのデカい CloudSQL、Valkeyは強いMemorystore 2 大 •WorkerサーバーはGCEのE シリーズ、CPUは2から順に上げていく
Premise •PostgreSQL、Valkeyがボトルネックにならないようにする •エンキュー/記録 アプリケーションのレイテンシは50ms以下 用 •アプリのDBは集計の関係で都度TRUNCATEするが、SolidQueueの テーブルはそのまま
Deploy •kamal •コンテナにもkamal経由で れるので集計とかも楽 立 ち上げるのが楽 入 •設定変えながらコンテナを
fi con g/deploy.yml
fi con g/queue.yml
fi con g/sidekiq.yml
fi con g/database.yml
いざ!
IO bound Job
IO bound Job SolidQueue Sidekiq/AJ 100 2CPU 3P/7T 2CPU 3P/2T 200 4CPU 5P/6T 4CPU 4P/6T 300 8CPU 8P/8T 8CPU 6P/6T 400 8CPU 8P/8T 8CPU 6P/6T 500 8CPU 10P/8T 8CPU 10P/6T 600 NA NA
IO bound Job • 縦がプロセス数、横がスレッド数 • 緑のマスは、その負荷とコア数の組み合わせで最速の組み合わせ • 黄色はスレッド数を増やして悪化した箇所、赤はプロセス数を増やして悪化した箇所 • 全ての組み合わせは試さず、100/sの負荷を見て計測の意味がありそうな箇所のみを選択
差があまりない •パラメータの違いはあれど、結果に差はほとんど無い •IOの時間があるので、GVLを回避して効率的にCPUが仕事してる •プロセス数を増やすほうが基本的に効果を感じられる、なぜか Sidekiqはスレッド数6が最も効率がよく、それ以外が悪い
CPU bound Job •集計結果が全然おもしろくなかったので割愛 •純粋にCPUを いつぶすので、ほぼ差が出なかった 行 食 •コア数分だけのJobが逐次実 される感じだし、Realworldにない
IO / CPU bound Job SolidQueue Sidekiq/AJ 100 8CPU 4P/4T 8CPU 4P/3T 200 NA NA
IO / CPU bound Job • 縦がプロセス数、横がスレッド数 • 緑のマスは、その負荷とコア数の組み合わせで最速の組み合わせ • 黄色はスレッド数を増やして悪化した箇所、赤はプロセス数を増やして悪化した箇所 • 全ての組み合わせは試さず、100/sの負荷を見て計測の意味がありそうな箇所のみを選択
あんまり変わらない •IOのJobは、どちらもほぼ同じ値に収束する •IOとCPUも似たような数値に収束しそう(まだ 分ではないが) 十 •おそらく、CPUでもIOでも単独だとあまり差が出ないので、それは そう……?
結論 そんなにかわらん もしかしたら、Sidekiqのほうがすこしはやいかも?
ちょっとまったー!
ActiveJobを介さないSidekiq
ActiveJobを介さないSidekiq? •SidekiqはActiveJobで管理せずとも単体で使 できる •公式ドキュメントにも、AJ使わないほうが速いと明記されている 用 •AJのシリアライズ/デシリアライズオーバーヘッドがある
app/controllers/job_conntroller.rb
con g/initializers/zeitwerk.rb fi これは別にやんなくてもいいかも
とはいえなぁ? •オーバーヘッドと っても、それno-opの話でしょ? 言 •実際にIOとCPUに負荷がかかる状態で、関係するの?
• 縦がプロセス数、横がスレッド数 • 緑のマスは、その負荷とコア数の組み合わせで最速の組み合わせ • 黄色はスレッド数を増やして悪化した箇所、赤はプロセス数を増やして悪化した箇所 • 全ての組み合わせは試さず、100/sの負荷を見て計測の意味がありそうな箇所のみを選択
IO bound Job SolidQueue Sidekiq/AJ Sidekiq/Nakid 100 2CPU 3P/7T 2CPU 3P/2T NA 200 4CPU 5P/6T 4CPU 4P/6T NA 300 8CPU 8P/8T 8CPU 6P/6T NA 400 8CPU 8P/8T 8CPU 6P/6T 8CPU 6P/6T 500 8CPU 10P/8T 8CPU 10P/6T 8CPU 6P/6T 600 NA NA 8CPU 6P/11T 700 NA NA 8CPU 11P/6T 800 NA NA NA
えっ •CPU bound のJobではあまり変わらない •IO bound のJobでは、明確に差が出た •CPU/IO boundのJobでは結局あまり変わらない
なんで? •理屈がよくわからない、なんで? •ActiveJob側になにか限界を縛るものがありそうだが、発 見 •プロファイラの分析が必要そう できず
もうすぐ終幕
所 •CPUを使うJobでは、CPUが占有されるのでコアが動ける数しか動 けない、あまりチューニングの余地なし •IOが多いJob(ネットワークやActiveRecord)はプロセス数を増や すと効くが、スレッド数が多すぎると悪化する傾向がある 見 •CPUとIOを半々くらいの場合、プロセス数xスレッド数がコア数を 少し超えるくらいを設定、多少増えても悪化したりはしない
所 2 •実際に仕事で使われるJobは、IOとCPUがどれくらいの をAPMなどで計測すると良いと思う 率なのか •とはいえ、やはり世の中のJobのメインはIOだと思うので、コア数 に合わせた 分なプロセス数を設定できると良いのではないか 比 十 見 •CPUがメインで使われるJobと、IOがメインで使われるJobはちゃ んとキューを分けてマシンも分離したほうがいい
所 3 •ではSidekiqとSolidQueueどちらを使うか、正直どちらでもいい •DBをギリギリまで使うタイプのアプリでなければSolidQueueを 使ったほうが構成は簡単、DBの負荷を少しでも減らすならSidekiq 見 •IOを酷使するようなJobが多い場合は、Naked Sidekiqが選択肢に なる
所 4 •あとは、それぞれの付加価値で考える •SolidQueueはRails標準、構成が簡単になるしSolid構成が何より体 験が良い、プロセスの管理もしやすい 長 見 •Sidekiqは い実績と、Enterpriseサポートがある、あとバルクイ ンサートやミドルウェアなど今回焦点にしなかった機能やメリット も多い
感想 •SolidQueueはプロセス数の変更が楽、Sidekiqは 性が悪い 倒でKamalと相 •管理画 はSidekiqのほうが圧倒的に良い、これだけでSidekiqを選 ぶ理由になり得る 面 面 •Workerサーバーのデプロイ、みんなどうしてんだろ……?
意外だったこと •ActiveJobを介さないSidekiqは、IOが多いJobで本当に早かった •CPUを使うタスクって全然スケールしないな、ということ •メモリ全然使わないな、ということ(Memory boundってあるの かな?)
やり残したこと •今回は負荷試験だったので、APMやトレースを取ってない •SolidQueueやSidekiqのソースコードレベルで原因を追えれば楽し そうだが、間に合わなかった 日 •詳細は後 にSmartHRのテックブログでもまとめます
まとめ •RealWorldでSolidQueue、Sidekiqは好きな を使えばいい •IOヘビーなJobはNaked Sidekiqが選択肢になる 方 •Jobの特性ごとにチューニングの余地はあるので、計測しよう