---
title: Job戦国時代
tags: 
author: [kinoppyd](https://docswell.com/user/kinoppyd)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/4EZLXR9373.jpg?width=480
description: こんにちは、小早川秀秋です 関ケ原Ruby会議01での登壇資料です
published: June 02, 26
canonical: https://docswell.com/s/kinoppyd/ZX24J3-job-sengoku-jidai
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/4EZLXR9373.jpg)

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


# Page. 2

![Page Image](https://bcdn.docswell.com/page/Y76W4RKZ7V.jpg)

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


# Page. 3

![Page Image](https://bcdn.docswell.com/page/G75MQ8P974.jpg)

世は


# Page. 4

![Page Image](https://bcdn.docswell.com/page/9J29PK65ER.jpg)

Job戦国時代
[要出典]


# Page. 5

![Page Image](https://bcdn.docswell.com/page/DEY45N96JM.jpg)



# Page. 6

![Page Image](https://bcdn.docswell.com/page/VJNYNXD178.jpg)



# Page. 7

![Page Image](https://bcdn.docswell.com/page/YE9PR8GYJ3.jpg)

2つの陣営が


# Page. 8

![Page Image](https://bcdn.docswell.com/page/GE8DW8VKED.jpg)

関ケ原で激突する！


# Page. 9

![Page Image](https://bcdn.docswell.com/page/LELMNR5P7R.jpg)



# Page. 10

![Page Image](https://bcdn.docswell.com/page/4JMYXR32JW.jpg)

🤗


# Page. 11

![Page Image](https://bcdn.docswell.com/page/PJR9NRQ579.jpg)

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


# Page. 12

![Page Image](https://bcdn.docswell.com/page/PEXQNR5XJX.jpg)

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


# Page. 13

![Page Image](https://bcdn.docswell.com/page/3EK9NR69ED.jpg)

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


# Page. 14

![Page Image](https://bcdn.docswell.com/page/L73WV86975.jpg)

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


# Page. 15

![Page Image](https://bcdn.docswell.com/page/87DK8MV8JG.jpg)

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


# Page. 16

![Page Image](https://bcdn.docswell.com/page/VJPK8RVWE8.jpg)

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


# Page. 17

![Page Image](https://bcdn.docswell.com/page/2EVVNRZ9EQ.jpg)

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


# Page. 18

![Page Image](https://bcdn.docswell.com/page/57GLKM44EL.jpg)

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


# Page. 19

![Page Image](https://bcdn.docswell.com/page/4EQYNRGRJP.jpg)

fi
con g/application.rb


# Page. 20

![Page Image](https://bcdn.docswell.com/page/KJ4WG85Q71.jpg)

fi
con g/routes.rb


# Page. 21

![Page Image](https://bcdn.docswell.com/page/LE1YD2WL7G.jpg)

bin/job


# Page. 22

![Page Image](https://bcdn.docswell.com/page/GEWGYR6QJ2.jpg)

app/controllers/job_conntroller.rb


# Page. 23

![Page Image](https://bcdn.docswell.com/page/47ZLXRY3J3.jpg)

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


# Page. 24

![Page Image](https://bcdn.docswell.com/page/YJ6W4RDZJV.jpg)

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


# Page. 25

![Page Image](https://bcdn.docswell.com/page/GJ5MQ839J4.jpg)

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


# Page. 26

![Page Image](https://bcdn.docswell.com/page/LE3WV862E5.jpg)

fi
con g/deploy.yml


# Page. 27

![Page Image](https://bcdn.docswell.com/page/8EDK8MV67G.jpg)

fi
con g/queue.yml


# Page. 28

![Page Image](https://bcdn.docswell.com/page/V7PK8RRZJ8.jpg)

fi
con g/sidekiq.yml


# Page. 29

![Page Image](https://bcdn.docswell.com/page/2JVVNRRMJQ.jpg)

fi
con g/database.yml


# Page. 30

![Page Image](https://bcdn.docswell.com/page/5EGLKMMXJL.jpg)

いざ！


# Page. 31

![Page Image](https://bcdn.docswell.com/page/4JQYNRR57P.jpg)

IO bound Job


# Page. 32

![Page Image](https://bcdn.docswell.com/page/K74WG88VE1.jpg)

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


# Page. 33

![Page Image](https://bcdn.docswell.com/page/LJ1YD224EG.jpg)

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


# Page. 34

![Page Image](https://bcdn.docswell.com/page/GJWGYRRZ72.jpg)

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


# Page. 35

![Page Image](https://bcdn.docswell.com/page/4EZLXRRL73.jpg)

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


# Page. 36

![Page Image](https://bcdn.docswell.com/page/Y76W4RRM7V.jpg)

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


# Page. 37

![Page Image](https://bcdn.docswell.com/page/G75MQ88Q74.jpg)

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


# Page. 38

![Page Image](https://bcdn.docswell.com/page/9J29PKKWER.jpg)

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


# Page. 39

![Page Image](https://bcdn.docswell.com/page/DEY45NN9JM.jpg)

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


# Page. 40

![Page Image](https://bcdn.docswell.com/page/VJNYNXXD78.jpg)

ちょっとまったー！


# Page. 41

![Page Image](https://bcdn.docswell.com/page/YE9PR888J3.jpg)



# Page. 42

![Page Image](https://bcdn.docswell.com/page/GE8DW88ZED.jpg)

ActiveJobを介さないSidekiq


# Page. 43

![Page Image](https://bcdn.docswell.com/page/LELMNRR17R.jpg)

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


# Page. 44

![Page Image](https://bcdn.docswell.com/page/4JMYXRR5JW.jpg)

app/controllers/job_conntroller.rb


# Page. 45

![Page Image](https://bcdn.docswell.com/page/PJR9NRRZ79.jpg)

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


# Page. 46

![Page Image](https://bcdn.docswell.com/page/PEXQNRR1JX.jpg)

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


# Page. 47

![Page Image](https://bcdn.docswell.com/page/3EK9NRRMED.jpg)

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


# Page. 48

![Page Image](https://bcdn.docswell.com/page/L73WV88275.jpg)



# Page. 49

![Page Image](https://bcdn.docswell.com/page/87DK8MM6JG.jpg)

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


# Page. 50

![Page Image](https://bcdn.docswell.com/page/VJPK8RQZE8.jpg)

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


# Page. 51

![Page Image](https://bcdn.docswell.com/page/2EVVNR5MEQ.jpg)

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


# Page. 52

![Page Image](https://bcdn.docswell.com/page/57GLKM6XEL.jpg)

もうすぐ終幕


# Page. 53

![Page Image](https://bcdn.docswell.com/page/4EQYNR45JP.jpg)

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


# Page. 54

![Page Image](https://bcdn.docswell.com/page/KJ4WG8QV71.jpg)

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


# Page. 55

![Page Image](https://bcdn.docswell.com/page/LE1YD2P47G.jpg)

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


# Page. 56

![Page Image](https://bcdn.docswell.com/page/GEWGYR2ZJ2.jpg)

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


# Page. 57

![Page Image](https://bcdn.docswell.com/page/47ZLXRDLJ3.jpg)

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


# Page. 58

![Page Image](https://bcdn.docswell.com/page/YJ6W4R1MJV.jpg)

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


# Page. 59

![Page Image](https://bcdn.docswell.com/page/GJ5MQ84QJ4.jpg)

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


# Page. 60

![Page Image](https://bcdn.docswell.com/page/9E29PKVW7R.jpg)

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


# Page. 61

![Page Image](https://bcdn.docswell.com/page/D7Y45N39EM.jpg)



# Page. 62

![Page Image](https://bcdn.docswell.com/page/VENYNXVDJ8.jpg)



