Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JavaアプリをKubernetesで動かすためのチューニングガイド / A tuning guide for running java apps on Kubernetes

hhiroshell
January 19, 2022

JavaアプリをKubernetesで動かすためのチューニングガイド / A tuning guide for running java apps on Kubernetes

#ochacafe Season 5 #1 のLTセッションの資料です。
https://ochacafe.connpass.com/event/232810/

hhiroshell

January 19, 2022
Tweet

More Decks by hhiroshell

Other Decks in Technology

Transcript

  1. 宣伝 • 感染対策をしっかりやって遊舎⼯房に⾏きましょう 2 遊舎⼯房さんの店舗はこちら→ ↓現在の@hhiroshellのキーボードたち #crkbd ⾃⼰紹介 @hhiroshell 早川

    博 (はやかわ ひろし) • Cloud Nativeなインフラを開発 するエンジニア。 Yahoo Japan Corporation 所属 • エンジニアコミュニティ 「Cloud Native Developers JP」 オーガナイザー • Developers Summit 2018 Japan Container Days 12.18 CloudNative Days Tokyo 2019, 2020, 2021 • ⾃作キーボード沼 BMEK
  2. Kubernetesにおけるリソース設定 • RequestsとLimitsとがある • Requests – コンテナのために最低限確保されるリソース • CPU /

    Memory / hugepages / ephemeral-storage • Requestsに指定したリソースを実際に使えることが保証 される • Limits – コンテナが利⽤できる最⼤のリソース • CPU / Memory / hugepages / ephemeral-storage • Nodeに空きがあるときに使⽤できる最⼤のリソース量 apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx:latest resources: requests: cpu: 0.5 memory: 1G limits: cpu: 1 memory: 2G 実利⽤量 Requests Limits 8
  3. 【参考】QoS(Quality of Service) Class • PodのEvictされやすさはQoS Classによって決まる • Guaranteed: –

    全てのコンテナの、CPUとMemoryのLimitsとRequestが設定されており、 Limits=Requestsとなっている場合にこれになる – Limitsのみ設定するとRequestsに同じ値が設定されるため、CPUと MemoryのLimitsのみを指定した場合もGuaranteedになる • Burstable: – Guaranteed、BestEffortに当てはまらない場合これになる • BestEffort: – 全てのコンテナでLimitsとRequestが設定されていない場合にこれになる Evict されづらい Evict され易い 11
  4. RequestsとLimitsにまつわるいろいろな挙動 – 3/3 • Limitsを超えたリソースを使おうとしたとき – CPUの場合:スロットリング • CPUの利⽤量がLimitの値を超えない状態で動作を継続 –

    メモリの場合:OOMKill • コンテナがKillされ、結果としてPodが再起動される • Nodeに余裕があってもLimitsを超えるリソースは使えない NodeのCPU or Memory全体 Limitsを超えないように 制御される 12
  5. Limitsの設定から影響を受けるJVMの挙動 • Limitsの設定値を認識してJVMが⼀部の挙動を⾃動的に変える • CPU – Limitsの設定値がコンテナの --cpu-shares にマッピングされる。これをJVMが認 識して動作する

    – 結果として、Runtime.availableProcessors()の返り値や、ForkJoinプール、スレッ ドプールの割当量が変わる。これらに依存して挙動を変えているライブラリ やフレームワークも影響を受ける (e.g., core.async, ElasticSearch, Netty) • メモリ – JVMのヒープメモリが、Limitsに対してエルゴノミクスによって決定される – これに従ってGCアルゴリズム等も決まる 15
  6. Javaアプリケーションが使うメモリの内訳 ① ヒープメモリ – ご存知ヒープメモリ。デフォルトではLimitsの値から動的に決定される(エルゴノミクス) ② スレッドスタック – 1スレッドごとに確保されるメモリ領域。デフォルトは1024K /

    Thread ③ コードキャッシュ – JITコンパイラによりコンパイルされたコードのキャッシュが保持される領域。デフォルトでは約240MB 消費メモリ合計 = ① ヒープメモリ + ② スレッドスタック + ③ コードキャッシュ + ④ メタスペース + ⑤ ダイレクトメモリ + ⑥ ネイティブメモリ 16
  7. Javaアプリケーションが使うメモリの内訳 ④ メタスペース – クラスメタデータが配置される領域。デフォルトでは無制限 ⑤ ダイレクトメモリ – New I/Oダイレクトバッファで使う領域。デフォルトでは無制限。アプリの利⽤に合わせて適宜追加で確保

    ⑥ ネイティブメモリ – ネイティブメソッドの実⾏に伴って消費される領域。上限値を設定することはできない 消費メモリ合計 = ① ヒープメモリ + ② スレッドスタック + ③ コードキャッシュ + ④ メタスペース + ⑤ ダイレクトメモリ + ⑥ ネイティブメモリ 17
  8. 設定例 19 apiVersion: v1 kind: Pod metadata: name: openjdk8 spec:

    containers: - image: openjdk:11-jdk-slim name: openjdk # ...(snip)... resources: requests: memory: 256Mi cpu: 0.25 limits: memory: 1Gi cpu: 1 env: - name: JAVA_TOOL_OPTIONS value: “-XX:MaxRAMPercentage=50.0 -XX:MaxMetaspaceSize=128M -XX:MaxDirectMemorySize=10M"
  9. チューニング時に意識すべきメモリ領域 • スレッドスタック、コードキャッシュは意外と消費が多いので、 ヒープメモリを除いた残りでこれが収まるように注意 – スレッドスタック: • Spring Bootでは最⼤コネクション数分のスレッド(デフォルト: 200)が⽣成される。

    1024K * 200 = 205M に、他のスレッド分が加わる – コードキャッシュ: • デフォルトでは最⼤約240M • コンテナではそれほど⼤きいメモリを割り当てないことが多い。 Limitsが1GBならヒープは50%程度にしておくと安全 • 実際は測って決める 20
  10. もっと本格的なチューニングは…。 • 実物で計測しながら各パラメータを調整して下さい…。m(_ _)m – > 推測するな、計測せよ c.f. https://qiita.com/e99h2121/items/e8f899756b21b0414835 •

    CloudFoundryのJava Buildpack Memory Calculatorも参考にできる – メモリパラメータの⾃動計算アルゴリズム公開されている 消費メモリ合計 = ① ヒープメモリ + ② スレッドスタック + ③ コードキャッシュ + ④ メタスペース + ⑤ ダイレクトメモリ + ⑥ ネイティブメモリ 21
  11. まとめ • KubernetesのPodにはResource Limits / Requestsを設定できる – Requests: コンテナのために最低限確保されるリソース –

    Limits: コンテナが利⽤できる最⼤のリソース • JVMはResource Limitsの設定値を受けて⼀部パラメータを⾃動調整す る • ヒープメモリはデフォルトに任せると⼗分にメモリを使えないので、 最⼤値を引き上げるのがおすすめ • 実際のチューニングは実物で計測しながらやりましょう 23
  12. 【参考⽂献】 • Resource Management for Pods and Containers – https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

    • Resource Requests and Limits Under the Hood: The Journey of a Pod Spec – https://speakerdeck.com/inductor/resource-requests-and-limits-under-the-hood-the- journey-of-a-pod-spec • Understanding CPU throttling in Kubernetes to improve application performance – https://speakerdeck.com/daikurosawa/understanding-cpu-throttling-in-kubernetes-to- improve-application-performance-number-k8sjp • Better Containerized JVMs in JDK10 – http://blog.gilliard.lol/2018/01/10/Java-in-containers-jdk10.html • CloudFoundry Java Buildpack Memory Calculator – https://github.com/cloudfoundry/java-buildpack-memory-calculator 26