$30 off During Our Annual Pro Sale. View Details »

[JJUG CCC 2022 fall] Fargate上のJVMからCPUを認識するまで 〜正しく認識されないCPUの謎を追え〜

orekyuu
November 27, 2022

[JJUG CCC 2022 fall] Fargate上のJVMからCPUを認識するまで 〜正しく認識されないCPUの謎を追え〜

orekyuu

November 27, 2022
Tweet

More Decks by orekyuu

Other Decks in Programming

Transcript

  1. Fargate上のJVMからCPUを認識するまで
    〜正しく認識されないCPUの謎を追え〜
    金川 祐太郎
    株式会社ディー・エヌ・エー

    View Slide

  2. 2
    自己紹介
    金川 祐太郎
    ● 所属: 株式会社ディー・エヌ・エー
    ● twitter: @orekyuu
    ● 最近の悩み: コロナ禍に入ってから太ってしまった
    久しぶりに登壇で顔を出したらTwitterで「顔のアス比かわったね」

    View Slide

  3. 3
    本日のゴール
    ● 今回の事例を例に、JVMがどのようにCPU数を認識しているかを知る
    非ゴール: ECSでJavaアプリケーションを使うためのコツや知見
    OpenJDKのコードを読むためのきっかけになれば幸いです

    View Slide

  4. 事例の紹介

    View Slide

  5. 5
    環境の紹介
    1
    ● Quarkus: 2.9.2
    ● JDK: amazon corretto 17
    ● quarkus-container-image-jibでビルドしたimageをECS fargateへdeploy

    View Slide

  6. 6
    GCのアルゴリズムを指定せず動かすとSerial GCになっている
    2
    ● 負荷試験でJFRの記録をとったところ、
    SerialGCが使われていることが分かった
    ● ECS Taskのcpuの指定は2048になっていて、
    G1 GCが使われるはず

    View Slide

  7. 7
    目次
    OpenJDKのGCに関する登場人物
    OpenJDKが使うGC選択の流れ
    AvailableProcessorsの検出の流れ
    1
    2
    3

    View Slide

  8. 8
    OpenJDKのGCに関する登場人物

    View Slide

  9. 9
    OpenJDKのディレクトリの構造
    ● src/hotspot以下にosやcpuアーキテクチャ毎の
    実装が書かれており、shareは共通の実装
    ● share以下は機能ごとにディレクトリが
    掘られている
    1

    View Slide

  10. 10
    登場人物
    1
    Arguments GCConfig GCArguments
    SerialArguments SerialArguments
    initialize
    GCの決定 GCアルゴリズムごとの引数
    GCアルゴリズムごとにサブクラスを持つ
    CollectedHeap
    createHeap

    View Slide

  11. 11
    登場人物
    1
    Arguments GCConfig GCArguments
    SerialArguments SerialArguments
    initialize
    GCの決定 GCアルゴリズムごとの引数
    GCアルゴリズムごとにサブクラスを持つ
    CollectedHeap
    createHeap

    View Slide

  12. 12
    OpenJDKが使うGC選択の流れ

    View Slide

  13. 13
    GCアルゴリズムの決定
    1

    View Slide

  14. 14
    GCアルゴリズムの決定
    1

    View Slide

  15. 15
    GCアルゴリズムの決定
    1
    起動オプションでGCが
    明示的に指定されていない

    View Slide

  16. 16
    GCアルゴリズムの決定
    1
    サーバークラスマシンなら G1GC
    そうでないならSerialGCを選んでいる

    View Slide

  17. 17
    GCアルゴリズムの決定
    1
    active_processor_countが2以上
    physical_memoryが約2GB以上
    右辺の変数は直前で宣言している

    View Slide

  18. 18
    jcmd VM.infoしてみる
    2
    initial active 1 になっている?

    View Slide

  19. AvailableProcessorsの検出の流れ

    View Slide

  20. 20
    active_processor_countの取得
    1
    os::active_processor_countはosごとに
    実装が異なる
    今回のイメージでは linuxの実装になる

    View Slide

  21. 21
    active_processor_countの取得
    1
    -XX:ActiveProcessorCountが
    指定されている場合

    View Slide

  22. 22
    active_processor_countの取得
    1
    コンテナのときはこちらの処理に入る

    View Slide

  23. ※ここから2022/08頃のコードです
    OpenJDKのmasterを見ていましたが、変更が入って処理の内容が変わっているためです

    View Slide

  24. 24
    active_processor_countの取得
    1
    CgroupSubsystemとは?

    View Slide

  25. 25
    寄り道: cgroups
    1
    ● linuxの機能で、プロセスの利用するリソースに制限をかけるもの
    ● dockerではcgroupsを活用しているらしく、コンテナ対応のコードでcgroups
    の名前が出てきた

    View Slide

  26. 26
    active_processor_countの取得
    1
    どうやらDockerコンテナのサポート
    っぽい

    View Slide

  27. 27
    active_processor_countの取得
    1
    share / 1024がshare_countになる

    View Slide

  28. 28
    active_processor_countの取得
    1
    最終的にcpu_countとlimit_countの
    小さい値がactive_processor_count

    View Slide

  29. 29
    active_processor_countの取得
    1
    これらのログを確認したい

    View Slide

  30. 30
    ログの確認
    2
    ● -Xlogオプションを使う
    ○ 今回の場合はjava -Xlog:os+container=trace -versionを
    ECSのコンテナ内で実行して検証

    View Slide

  31. 31
    ログの確認
    2
    CPU Sharesが2になっている?

    View Slide

  32. 32
    active_processor_countの取得
    1
    share / 1024がshare_countになる

    View Slide

  33. 33
    原因を知る
    3
    ● 「詳解: Amazon ECS による CPU とメモリのリソース管理」という記事を読

    View Slide

  34. 34
    原因を知る
    3
    コンテナにCPUユニットを設定しない場合、 2を設定します

    View Slide

  35. 35
    原因を知る
    3
    ● ECSにはTask DefinitionとContainer Definitionの両方にCPUの制限をつけられ

    ● JVMが見ているのはContainer DefinitionのCPU制限で、指定をしない場合は2
    になる

    View Slide

  36. 36
    まとめ
    3
    ● ECSにはTask DefinitionとContainer Definitionの両方にCPU制限があり、JVM
    が見るのはContainerの方なので必ず宣言しよう
    ● GCは明示的に指定しない場合、意図しないGCになる場合があるので明示的
    に宣言しておくと安心
    ● -Xlogオプションでログを出力できるので、デバッグする際には活用
    してみよう
    ● JDKのコードを読むのは怖くない!みんな読もう!

    View Slide