Kubernetes의 JVM 14 메모리에 대한 실용적인 가이드

이 기사는 현대 JVM이 컨테이너에서 메모리를 처리하는 방법에 대한 직접적인 대답을 얻은 좌절감에서 비롯되었습니다. 황동 압정으로 바로 가자.

JDK 14의 JVM은 기본적으로 UseContainerSupport 켜져 있습니다. 다음은 몇 가지 흥미로운 기본값입니다.

실행하여 직접 볼 수 있습니다.

docker run -m 1GB openjdk:14 java \
            -XX:+PrintFlagsFinal -version \
            | grep -E "UseContainerSupport | InitialRAMPercentage | MaxRAMPercentage | MinRAMPercentage | MinHeapFreeRatio | MaxHeapFreeRatio"


출력:

    double InitialRAMPercentage                      = 1.562500                                  {product} {default}
      uintx MaxHeapFreeRatio                         = 70                                     {manageable} {default}
     double MaxRAMPercentage                         = 25.000000                                 {product} {default}
      uintx MinHeapFreeRatio                         = 40                                     {manageable} {default}
     double MinRAMPercentage                         = 50.000000                                 {product} {default}
       bool UseContainerSupport                      = true                                      {product} {default}
  openjdk version "14.0.2" 2020-07-14
  OpenJDK Runtime Environment (build 14.0.2+12-46)
  OpenJDK 64-Bit Server VM (build 14.0.2+12-46, mixed mode, sharing)

MaxRAMPercentage가 여기서 핵심입니다. JVM의 기본값은 25%입니다.
MinRAMPercentageInitialRAMPercentage는 까다롭습니다. this Stackoverflow answer is the best explanation I've read so far .

다음은 해당 게시물을 간략하게 요약한 것입니다.
InitialRAMPercentage - InitialHeapSizeXms가 설정되지 않은 경우 사용됩니다. 이 경우 InitialHeapSize가 0이면 Source reference . 나는 이것을 예상대로 작동하게 하는 많은 운이 없었습니다.
MinRAMPercentage - MaxHeapSizeXmx가 설정되지 않은 경우 사용됩니다. 이 경우 의미를 설정하지 않고 MaxHeapSize, Xmx에 대한 기본값이 없습니다. Source reference .

MaxRAMPercentage 및 Kubernetes



아래 관찰은 simple memory testing application I wrote 을 사용한 일부 테스트를 기반으로 합니다.

dockerfile을 편집하여 MaxRAMPercentage(및 기타 JVM 인수)를 설정할 수 있습니다.

ENTRYPOINT 
["java","-XX:InitialRAMPercentage=10","-XX:MaxRAMPercentage=75","-jar","/app.jar"]


Limits and requests은 다음을 사용하여 설정됩니다.

  resources:
    limits:
      memory: 2Gi
    requests:
      memory: 2Gi


포드에 제한이 설정되지 않은 경우



JVM은 노드 메모리의 MaxRAMPercentage까지 사용합니다. 포드가 노드의 메모리 제한에 도달하면 Kubernetes는 OOM 예외를 발생시키지 않고 포드를 종료합니다.

컨테이너에 설정된 제한



MaxRAMPercentage가 100% 미만인 경우



JVM은 제한의 MaxRAMPercentage까지 사용합니다. OOM 예외를 발생시키는 대신 포드가 종료되지 않습니다.

100% MaxRAMPercentage의 경우



JVM은 메모리 제한의 100%를 사용합니다. 나는 이것이 때때로 OOM 예외를 던지는 것을 보았습니다. 지속적인 메모리 압박으로 Kubernetes는 포드를 종료합니다.

무엇을 최대로 설정할까요?



포드당 단일 컨테이너를 실행한다고 가정할 때 기본값으로 25%는 MaxRAMPercentage 에 대해 상대적으로 낮은 것으로 보입니다. 애플리케이션에 대해 무엇으로 설정해야 합니까?

이 질문에는 단호한 답변이 없습니다. 나는 100%가 나쁜 생각이라고 말할 수 있지만 최적의 것은 애플리케이션의 메모리 풋프린트(Metaspace에 대한 시스템 메모리를 사용하는 JVM 사용)와 사용 중인 컨테이너에 따라 달라집니다.

나는 항상 OS를 위해 최소한 1기가를 남겨둬야 한다는 조언을 들었습니다. 저도 75% 추천이라고 들었습니다. 개인적으로 우리는 우리의 응용 프로그램에 80 %를 사용하고 있지만 필요에 따라 계속 주시하고 조정하고 있습니다. 진실은 앱에 대해 몇 가지 다른 구성을 테스트하고 어떤 것이 적합한지 확인해야 한다는 것입니다.

요청은 어떻습니까?



요청은 흥미로운 것입니다. 나는 그것들이 JVM의 시작 힙 크기에 영향을 미치는 것을 보지 못했기 때문에 다른 K8 포드와 마찬가지로 노드 스케줄링에 사용됩니다. JVM은 힙 크기를 늘린 다음 절대 돌려주지 않거나 설정에 따라 아주 천천히 돌려주는 경향이 있습니다. (힙 재확보는 다른 게시물에 대해 충분히 큰 주제입니다.)

개인적으로 요청을 내 한도의 50%로 설정했습니다. 애플리케이션이 최대 힙에 도달하는 속도에 따라 Kubernetes가 애플리케이션을 적절한 노드에 배치하는 데 도움이 되도록 이를 제한의 100%로 설정할 수도 있습니다.


그것은 많은 연구의 짧은 버전이며 TLDR에 가깝고 복잡한 주제에 대해 얻을 수 있습니다. JDK 15를 모퉁이 돌면 눈에 띄는 변경 사항이 있으면 수정하려고 합니다.

내가 놓친 팁이 있습니까? 아래에 알려주십시오.

추가 리소스 / 참조



이들 중 일부는 JDK pre-14와 관련이 있습니다.
  • https://medium.com/@yortuc/jvm-memory-allocation-in-docker-container-a26bbce3a3f2
  • https://medium.com/adorsys/jvm-memory-settings-in-a-container-environment-64b0840e1d9e
  • https://stackoverflow.com/questions/54591870/mismatch-between-spring-actuators-jvm-memory-max-metric-and-runtime-getruntim
  • https://merikan.com/2019/04/jvm-in-a-container/
  • https://srvaroa.github.io/jvm/kubernetes/memory/docker/oomkiller/2019/05/29/k8s-and-java.html
  • https://stackoverflow.com/questions/54292282/clarification-of-meaning-new-jvm-memory-parameters-initialrampercentage-and-minr
  • https://blog.nebrass.fr/playing-with-the-jvm-inside-docker-containers/
  • 좋은 웹페이지 즐겨찾기