Job戦国時代

-- Views

June 02, 26

スライド概要

こんにちは、小早川秀秋です
関ケ原Ruby会議01での登壇資料です

profile-image

どういうわけか暑がり

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

(ダウンロード不可)

関連スライド

各ページのテキスト
1.

Job戦国時代 紅玉宿禰木下赤羽守ppyd翔央 @ 青色人労

2.

やあやあ、遠からん者は音にも聞け、 近くば寄って目にも見よ。 我こそは、父を筑前国に持ち、母を 河内国に仰ぎ、河内の地に生を享け、 幼き日を武蔵国にて過ごせし者。 幼少の砌より紅玉の武に身を投じ、 ついには暗黒の位を賜りし者なり。 今は蒼色人労の地にて武の道を磨き、 近頃は微小紅玉の術理を究めんと、 新たなる技の研鑽に励むものなり。

3.

世は

4.

Job戦国時代 [要出典]

7.

2つの陣営が

8.

関ケ原で激突する!

10.

🤗

11.

SolidQueue vs Sidekiq •簡易的なベンチマークは世の中に溢れている •だが、実際の業務で使うようなJobでのベンチマークは少ない •現実のユースケースではどうなのか……俺バカだからやってみない とわかんねえ

12.

Job in Real World? •SidekiqのWikiなどで指標に使われるのは、no-opなJob •現実では、当然ながらCPUとIOを使う •秒間に数百のJobが積まれていくと、レイテンシはどうなるのか?

13.

Benchmark •Jobは、IO bound、CPU bound、両 使うの3種を 意 •RailsアプリにPOSTすると、Jobがエンキューする構成 用 方 •エンキュー前にJobオブジェクトを保存しておき、後から集計する

14.

CPU / IO bound •CPU boundはBcryptを使ってパスワードのハッシュ化 •IO boundはHTTPリクエストを送信して結果を待つ •現実ではおそらく CPU < IO ではないかなと思う

15.

Metrics •エンキューから開始までのレイテンシ •開始から完了までのレイテンシ . を 見 5 9 、p 9 9 、p 9 0 、p 9 0 5 •リクエスト数変えながら p てみる

16.

Strategy •k を使い、1分間ウォームアップしながら100/sのリクエスト6分間 •統計 のJobオブジェクトを作成時間基準で10秒フレームに分類 9 9 用 6 •各フレームp で1秒以下のレイテンシをクリアすれば、追加100/s

17.

Parameters •VMのCPUコア数 2/4/8 •SolidQueue/Sidekiq のプロセス数 1-10 •SolidQueue/Sidekiqのスレッド数 3-15

18.

Application •sekigahara(https://github.com/kufu/sekigahara) •JobをキックするEast(worker_ignitor)と、Jobからリクエストを 受けるWest(hook_receiver) 一 •起動時の環境変数で、SolidQueueとSidekiqを切り替えられるよう にしたので、単 のコンテナで試験可能

19.

fi con g/application.rb

20.

fi con g/routes.rb

21.

bin/job

22.

app/controllers/job_conntroller.rb

23.

Environment •Google Cloud •Webアプリは 量のCloudRun、DBはPostgreSQLのデカい CloudSQL、Valkeyは強いMemorystore 2 大 •WorkerサーバーはGCEのE シリーズ、CPUは2から順に上げていく

24.

Premise •PostgreSQL、Valkeyがボトルネックにならないようにする •エンキュー/記録 アプリケーションのレイテンシは50ms以下 用 •アプリのDBは集計の関係で都度TRUNCATEするが、SolidQueueの テーブルはそのまま

25.

Deploy •kamal •コンテナにもkamal経由で れるので集計とかも楽 立 ち上げるのが楽 入 •設定変えながらコンテナを

26.

fi con g/deploy.yml

27.

fi con g/queue.yml

28.

fi con g/sidekiq.yml

29.

fi con g/database.yml

30.

いざ!

31.

IO bound Job

32.

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

33.

IO bound Job • 縦がプロセス数、横がスレッド数 • 緑のマスは、その負荷とコア数の組み合わせで最速の組み合わせ • 黄色はスレッド数を増やして悪化した箇所、赤はプロセス数を増やして悪化した箇所 • 全ての組み合わせは試さず、100/sの負荷を見て計測の意味がありそうな箇所のみを選択

34.

差があまりない •パラメータの違いはあれど、結果に差はほとんど無い •IOの時間があるので、GVLを回避して効率的にCPUが仕事してる •プロセス数を増やすほうが基本的に効果を感じられる、なぜか Sidekiqはスレッド数6が最も効率がよく、それ以外が悪い

35.

CPU bound Job •集計結果が全然おもしろくなかったので割愛 •純粋にCPUを いつぶすので、ほぼ差が出なかった 行 食 •コア数分だけのJobが逐次実 される感じだし、Realworldにない

36.

IO / CPU bound Job SolidQueue Sidekiq/AJ 100 8CPU 4P/4T 8CPU 4P/3T 200 NA NA

37.

IO / CPU bound Job • 縦がプロセス数、横がスレッド数 • 緑のマスは、その負荷とコア数の組み合わせで最速の組み合わせ • 黄色はスレッド数を増やして悪化した箇所、赤はプロセス数を増やして悪化した箇所 • 全ての組み合わせは試さず、100/sの負荷を見て計測の意味がありそうな箇所のみを選択

38.

あんまり変わらない •IOのJobは、どちらもほぼ同じ値に収束する •IOとCPUも似たような数値に収束しそう(まだ 分ではないが) 十 •おそらく、CPUでもIOでも単独だとあまり差が出ないので、それは そう……?

39.

結論 そんなにかわらん もしかしたら、Sidekiqのほうがすこしはやいかも?

40.

ちょっとまったー!

42.

ActiveJobを介さないSidekiq

43.

ActiveJobを介さないSidekiq? •SidekiqはActiveJobで管理せずとも単体で使 できる •公式ドキュメントにも、AJ使わないほうが速いと明記されている 用 •AJのシリアライズ/デシリアライズオーバーヘッドがある

44.

app/controllers/job_conntroller.rb

45.

con g/initializers/zeitwerk.rb fi これは別にやんなくてもいいかも

46.

とはいえなぁ? •オーバーヘッドと っても、それno-opの話でしょ? 言 •実際にIOとCPUに負荷がかかる状態で、関係するの?

47.

• 縦がプロセス数、横がスレッド数 • 緑のマスは、その負荷とコア数の組み合わせで最速の組み合わせ • 黄色はスレッド数を増やして悪化した箇所、赤はプロセス数を増やして悪化した箇所 • 全ての組み合わせは試さず、100/sの負荷を見て計測の意味がありそうな箇所のみを選択

49.

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

50.

えっ •CPU bound のJobではあまり変わらない •IO bound のJobでは、明確に差が出た •CPU/IO boundのJobでは結局あまり変わらない

51.

なんで? •理屈がよくわからない、なんで? •ActiveJob側になにか限界を縛るものがありそうだが、発 見 •プロファイラの分析が必要そう できず

52.

もうすぐ終幕

53.

所 •CPUを使うJobでは、CPUが占有されるのでコアが動ける数しか動 けない、あまりチューニングの余地なし •IOが多いJob(ネットワークやActiveRecord)はプロセス数を増や すと効くが、スレッド数が多すぎると悪化する傾向がある 見 •CPUとIOを半々くらいの場合、プロセス数xスレッド数がコア数を 少し超えるくらいを設定、多少増えても悪化したりはしない

54.

所 2 •実際に仕事で使われるJobは、IOとCPUがどれくらいの をAPMなどで計測すると良いと思う 率なのか •とはいえ、やはり世の中のJobのメインはIOだと思うので、コア数 に合わせた 分なプロセス数を設定できると良いのではないか 比 十 見 •CPUがメインで使われるJobと、IOがメインで使われるJobはちゃ んとキューを分けてマシンも分離したほうがいい

55.

所 3 •ではSidekiqとSolidQueueどちらを使うか、正直どちらでもいい •DBをギリギリまで使うタイプのアプリでなければSolidQueueを 使ったほうが構成は簡単、DBの負荷を少しでも減らすならSidekiq 見 •IOを酷使するようなJobが多い場合は、Naked Sidekiqが選択肢に なる

56.

所 4 •あとは、それぞれの付加価値で考える •SolidQueueはRails標準、構成が簡単になるしSolid構成が何より体 験が良い、プロセスの管理もしやすい 長 見 •Sidekiqは い実績と、Enterpriseサポートがある、あとバルクイ ンサートやミドルウェアなど今回焦点にしなかった機能やメリット も多い

57.

感想 •SolidQueueはプロセス数の変更が楽、Sidekiqは 性が悪い 倒でKamalと相 •管理画 はSidekiqのほうが圧倒的に良い、これだけでSidekiqを選 ぶ理由になり得る 面 面 •Workerサーバーのデプロイ、みんなどうしてんだろ……?

58.

意外だったこと •ActiveJobを介さないSidekiqは、IOが多いJobで本当に早かった •CPUを使うタスクって全然スケールしないな、ということ •メモリ全然使わないな、ということ(Memory boundってあるの かな?)

59.

やり残したこと •今回は負荷試験だったので、APMやトレースを取ってない •SolidQueueやSidekiqのソースコードレベルで原因を追えれば楽し そうだが、間に合わなかった 日 •詳細は後 にSmartHRのテックブログでもまとめます

60.

まとめ •RealWorldでSolidQueue、Sidekiqは好きな を使えばいい •IOヘビーなJobはNaked Sidekiqが選択肢になる 方 •Jobの特性ごとにチューニングの余地はあるので、計測しよう