developer tip

컨테이너가 메모리 제한을 초과하여 실행 중입니다.

copycodes 2020. 10. 26. 08:06
반응형

컨테이너가 메모리 제한을 초과하여 실행 중입니다.


Hadoop v1에서는 7 개의 매퍼와 리듀서 슬롯을 1GB 크기로 할당했으며 매퍼와 리듀서는 잘 실행됩니다. 내 컴퓨터에는 8G 메모리, 8 프로세서가 있습니다. 이제 YARN을 사용하면 동일한 시스템에서 동일한 응용 프로그램을 실행할 때 컨테이너 오류가 발생합니다. 기본적으로 다음 설정이 있습니다.

  <property>
    <name>yarn.scheduler.minimum-allocation-mb</name>
    <value>1024</value>
  </property>
  <property>
    <name>yarn.scheduler.maximum-allocation-mb</name>
    <value>8192</value>
  </property>
  <property>
    <name>yarn.nodemanager.resource.memory-mb</name>
    <value>8192</value>
  </property>

오류가 발생했습니다.

Container [pid=28920,containerID=container_1389136889967_0001_01_000121] is running beyond virtual memory limits. Current usage: 1.2 GB of 1 GB physical memory used; 2.2 GB of 2.1 GB virtual memory used. Killing container.

그런 다음 mapred-site.xml에서 메모리 제한을 설정하려고했습니다.

  <property>
    <name>mapreduce.map.memory.mb</name>
    <value>4096</value>
  </property>
  <property>
    <name>mapreduce.reduce.memory.mb</name>
    <value>4096</value>
  </property>

하지만 여전히 오류가 발생합니다.

Container [pid=26783,containerID=container_1389136889967_0009_01_000002] is running beyond physical memory limits. Current usage: 4.2 GB of 4 GB physical memory used; 5.2 GB of 8.4 GB virtual memory used. Killing container.

지도 작업에 이렇게 많은 메모리가 필요한 이유가 혼란 스럽습니다. 내 이해에서 1GB의 메모리는 내지도 / 축소 작업에 충분합니다. 컨테이너에 더 많은 메모리를 할당하면 작업이 더 많이 사용하는 이유는 무엇입니까? 각 작업이 더 많은 분할을 받기 때문입니까? 더 많은 작업이 병렬로 실행되도록 컨테이너 크기를 약간 줄이고 더 많은 컨테이너를 만드는 것이 더 효율적이라고 생각합니다. 문제는 각 컨테이너에 처리 할 수있는 것보다 더 많은 분할이 할당되지 않도록하려면 어떻게해야합니까?


또한 MapReduce에 대한 최대 메모리 할당을 올바르게 구성해야합니다. 에서 이 호튼 웍스 튜토리얼 :

[...]

클러스터의 각 머신에는 48GB의 RAM이 있습니다. 이 RAM 중 일부는 운영 체제 사용을 위해> 예약되어야합니다. 각 노드에서> YARN에 대해 40GB RAM을 할당하고 운영 체제에 대해 8GB를 유지합니다.

예제 클러스터의 경우 컨테이너 (yarn.scheduler.minimum-allocation-mb) = 2GB에 대한 최소 RAM이 있습니다. 따라서 Map 작업 컨테이너에 4GB를 할당하고 Reduce 작업 컨테이너에 8GB를 할당합니다.

mapred-site.xml에서 :

mapreduce.map.memory.mb: 4096

mapreduce.reduce.memory.mb: 8192

각 컨테이너는 매핑 및 축소 작업을 위해 JVM을 실행합니다. JVM 힙 크기는 위에서 정의한 Map 및 Reduce 메모리보다 낮게 설정하여 YARN에서 할당 한 컨테이너 메모리의 경계 내에 있어야합니다.

mapred-site.xml에서 :

mapreduce.map.java.opts: -Xmx3072m

mapreduce.reduce.java.opts: -Xmx6144m

위의 설정 은 매핑 및 축소 작업이 사용할 물리적 RAM의 상한을 구성합니다 .

그것을 요 ​​약하기:

  1. YARN에서는 mapreduce구성이 아닌 구성 을 사용해야 mapred합니다. 수정 : 질문을 수정 했으므로이 댓글은 더 이상 적용되지 않습니다.
  2. 구성하는 것은 실제로 할당 할 최대 값이 아니라 요청하려는 양입니다.
  3. 최대 제한은 java.opts위에 나열된 설정 으로 구성됩니다 .

마지막으로 유사한 문제 (및 솔루션)를 설명하는 이 다른 SO 질문 을 확인할 수 있습니다 .


가상 및 실제 메모리 사용 비율에 대해 Yarn 수준에서 확인됩니다. VM에 충분한 물리적 메모리가 없다는 것이 문제가 아닙니다. 그러나 가상 메모리 사용량이 주어진 물리적 메모리에 대해 예상보다 많기 때문입니다.

참고 : 이것은 가상 메모리의 적극적인 할당으로 인해 Centos / RHEL 6에서 발생합니다.

다음 방법 중 하나로 해결할 수 있습니다.

  1. yarn.nodemanager.vmem-check-enabledfalse 로 설정 하여 가상 메모리 사용량 확인을 비활성화하십시오 .

  2. yarn.nodemanager.vmem-pmem-ratio 를 더 높은 값 으로 설정하여 VM : PM 비율을 높입니다.

참고 문헌 :

https://issues.apache.org/jira/browse/HADOOP-11364

http://blog.cloudera.com/blog/2014/04/apache-hadoop-yarn-avoiding-6-time-sumption-gotchas/

yarn-site.xml에 다음 속성 추가

 <property>
   <name>yarn.nodemanager.vmem-check-enabled</name>
    <value>false</value>
    <description>Whether virtual memory limits will be enforced for containers</description>
  </property>
 <property>
   <name>yarn.nodemanager.vmem-pmem-ratio</name>
    <value>4</value>
    <description>Ratio between virtual memory to physical memory when setting memory limits for containers</description>
  </property>

EMR에서 HIVE를 사용하면 정말 비슷한 문제가 발생했습니다. 현존하는 솔루션 중 어느 것도 저에게 효과가 없었습니다. 즉, mapreduce 구성이 저에게 효과가 없었습니다. 둘 다 yarn.nodemanager.vmem-check-enabled거짓으로 설정하지 않았습니다 .

그러나 결국 작동하는 것은 설정이었습니다 tez.am.resource.memory.mb.

hive -hiveconf tez.am.resource.memory.mb=4096

조정을 고려할 또 다른 설정은 yarn.app.mapreduce.am.resource.mb


I can't comment on the accepted answer, due to low reputation. However, I would like to add, this behavior is by design. The NodeManager is killing your container. It sounds like you are trying to use hadoop streaming which is running as a child process of the map-reduce task. The NodeManager monitors the entire process tree of the task and if it eats up more memory than the maximum set in mapreduce.map.memory.mb or mapreduce.reduce.memory.mb respectively, we would expect the Nodemanager to kill the task, otherwise your task is stealing memory belonging to other containers, which you don't want.


While working with spark in EMR I was having the same problem and setting maximizeResourceAllocation=true did the trick; hope it helps someone. You have to set it when you create the cluster. From the EMR docs:

aws emr create-cluster --release-label emr-5.4.0 --applications Name=Spark \
--instance-type m3.xlarge --instance-count 2 --service-role EMR_DefaultRole --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole --configurations https://s3.amazonaws.com/mybucket/myfolder/myConfig.json

Where myConfig.json should say:

[
  {
    "Classification": "spark",
    "Properties": {
      "maximizeResourceAllocation": "true"
    }
  }
]

We also faced this issue recently. If the issue is related to mapper memory, couple of things I would like to suggest that needs to be checked are.

  • Check if combiner is enabled or not? If yes, then it means that reduce logic has to be run on all the records (output of mapper). This happens in memory. Based on your application you need to check if enabling combiner helps or not. Trade off is between the network transfer bytes and time taken/memory/CPU for the reduce logic on 'X' number of records.
    • If you feel that combiner is not much of value, just disable it.
    • If you need combiner and 'X' is a huge number (say millions of records) then considering changing your split logic (For default input formats use less block size, normally 1 block size = 1 split) to map less number of records to a single mapper.
  • Number of records getting processed in a single mapper. Remember that all these records need to be sorted in memory (output of mapper is sorted). Consider setting mapreduce.task.io.sort.mb (default is 200MB) to a higher value if needed. mapred-configs.xml
  • If any of the above didn't help, try to run the mapper logic as a standalone application and profile the application using a Profiler (like JProfiler) and see where the memory getting used. This can give you very good insights.

참고URL : https://stackoverflow.com/questions/21005643/container-is-running-beyond-memory-limits

반응형