Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Fargate上のJVMからCPUを認識するまで 〜正しく認識されないCPUの謎を追え〜 金川 祐太郎 株式会社ディー・エヌ・エー
Slide 2
Slide 2 text
2 自己紹介 金川 祐太郎 ● 所属: 株式会社ディー・エヌ・エー ● twitter: @orekyuu ● 最近の悩み: コロナ禍に入ってから太ってしまった 久しぶりに登壇で顔を出したらTwitterで「顔のアス比かわったね」
Slide 3
Slide 3 text
3 本日のゴール ● 今回の事例を例に、JVMがどのようにCPU数を認識しているかを知る 非ゴール: ECSでJavaアプリケーションを使うためのコツや知見 OpenJDKのコードを読むためのきっかけになれば幸いです
Slide 4
Slide 4 text
事例の紹介
Slide 5
Slide 5 text
5 環境の紹介 1 ● Quarkus: 2.9.2 ● JDK: amazon corretto 17 ● quarkus-container-image-jibでビルドしたimageをECS fargateへdeploy
Slide 6
Slide 6 text
6 GCのアルゴリズムを指定せず動かすとSerial GCになっている 2 ● 負荷試験でJFRの記録をとったところ、 SerialGCが使われていることが分かった ● ECS Taskのcpuの指定は2048になっていて、 G1 GCが使われるはず
Slide 7
Slide 7 text
7 目次 OpenJDKのGCに関する登場人物 OpenJDKが使うGC選択の流れ AvailableProcessorsの検出の流れ 1 2 3
Slide 8
Slide 8 text
8 OpenJDKのGCに関する登場人物
Slide 9
Slide 9 text
9 OpenJDKのディレクトリの構造 ● src/hotspot以下にosやcpuアーキテクチャ毎の 実装が書かれており、shareは共通の実装 ● share以下は機能ごとにディレクトリが 掘られている 1
Slide 10
Slide 10 text
10 登場人物 1 Arguments GCConfig GCArguments SerialArguments SerialArguments initialize GCの決定 GCアルゴリズムごとの引数 GCアルゴリズムごとにサブクラスを持つ CollectedHeap createHeap
Slide 11
Slide 11 text
11 登場人物 1 Arguments GCConfig GCArguments SerialArguments SerialArguments initialize GCの決定 GCアルゴリズムごとの引数 GCアルゴリズムごとにサブクラスを持つ CollectedHeap createHeap
Slide 12
Slide 12 text
12 OpenJDKが使うGC選択の流れ
Slide 13
Slide 13 text
13 GCアルゴリズムの決定 1
Slide 14
Slide 14 text
14 GCアルゴリズムの決定 1
Slide 15
Slide 15 text
15 GCアルゴリズムの決定 1 起動オプションでGCが 明示的に指定されていない
Slide 16
Slide 16 text
16 GCアルゴリズムの決定 1 サーバークラスマシンなら G1GC そうでないならSerialGCを選んでいる
Slide 17
Slide 17 text
17 GCアルゴリズムの決定 1 active_processor_countが2以上 physical_memoryが約2GB以上 右辺の変数は直前で宣言している
Slide 18
Slide 18 text
18 jcmd VM.infoしてみる 2 initial active 1 になっている?
Slide 19
Slide 19 text
AvailableProcessorsの検出の流れ
Slide 20
Slide 20 text
20 active_processor_countの取得 1 os::active_processor_countはosごとに 実装が異なる 今回のイメージでは linuxの実装になる
Slide 21
Slide 21 text
21 active_processor_countの取得 1 -XX:ActiveProcessorCountが 指定されている場合
Slide 22
Slide 22 text
22 active_processor_countの取得 1 コンテナのときはこちらの処理に入る
Slide 23
Slide 23 text
※ここから2022/08頃のコードです OpenJDKのmasterを見ていましたが、変更が入って処理の内容が変わっているためです
Slide 24
Slide 24 text
24 active_processor_countの取得 1 CgroupSubsystemとは?
Slide 25
Slide 25 text
25 寄り道: cgroups 1 ● linuxの機能で、プロセスの利用するリソースに制限をかけるもの ● dockerではcgroupsを活用しているらしく、コンテナ対応のコードでcgroups の名前が出てきた
Slide 26
Slide 26 text
26 active_processor_countの取得 1 どうやらDockerコンテナのサポート っぽい
Slide 27
Slide 27 text
27 active_processor_countの取得 1 share / 1024がshare_countになる
Slide 28
Slide 28 text
28 active_processor_countの取得 1 最終的にcpu_countとlimit_countの 小さい値がactive_processor_count
Slide 29
Slide 29 text
29 active_processor_countの取得 1 これらのログを確認したい
Slide 30
Slide 30 text
30 ログの確認 2 ● -Xlogオプションを使う ○ 今回の場合はjava -Xlog:os+container=trace -versionを ECSのコンテナ内で実行して検証
Slide 31
Slide 31 text
31 ログの確認 2 CPU Sharesが2になっている?
Slide 32
Slide 32 text
32 active_processor_countの取得 1 share / 1024がshare_countになる
Slide 33
Slide 33 text
33 原因を知る 3 ● 「詳解: Amazon ECS による CPU とメモリのリソース管理」という記事を読 む
Slide 34
Slide 34 text
34 原因を知る 3 コンテナにCPUユニットを設定しない場合、 2を設定します
Slide 35
Slide 35 text
35 原因を知る 3 ● ECSにはTask DefinitionとContainer Definitionの両方にCPUの制限をつけられ る ● JVMが見ているのはContainer DefinitionのCPU制限で、指定をしない場合は2 になる
Slide 36
Slide 36 text
36 まとめ 3 ● ECSにはTask DefinitionとContainer Definitionの両方にCPU制限があり、JVM が見るのはContainerの方なので必ず宣言しよう ● GCは明示的に指定しない場合、意図しないGCになる場合があるので明示的 に宣言しておくと安心 ● -Xlogオプションでログを出力できるので、デバッグする際には活用 してみよう ● JDKのコードを読むのは怖くない!みんな読もう!