복붙노트

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

HADOOP

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

나는 며칠 동안 distcp와 어려움을 겪어 왔고 나는 맹세했다. 여기에 나의 유스 케이스가있다.

나는 특정 위치에 / hdfs / root라는 메인 폴더를 가지고 있는데, 많은 서브 디렉토리들 (깊이는 고정되어 있지 않다)과 파일들이있다.

볼륨 : 200,000 개 파일 ~ 30 개 GO

클라이언트의 서브 세트, / hdfs / root를 다른 위치, 즉 / hdfs / dest에 복사해야합니다. 이 서브 세트는 시간 경과에 따라 갱신 될 수있는 절대 경로 목록으로 정의됩니다.

볼륨 : 50,000 개 파일 ~ = 5 개 GO

최적화되지 않았고 모든 파일을 가져 오며 업데이트 모드가 아니기 때문에 간단한 hdfs dfs -cp / hdfs / root / hdfs dest를 사용할 수 없다는 것을 알고 있습니다.

나는 두 가지 방법으로 hadoop distcp를 사용했다.

Algo 1 (simplified):
# I start up to N distcp jobs in parallel for each subdir, with N=MAX_PROC (~30)

foreach subdir in mylist: 
    # mylist = /hdfs/root/dirX/file1 /hdfs/root/dirX/file2 ...
    mylist = buildList(subdirs)
    hadoop distcp -i -pct -update mylist /hdfs/dest/subdir &

Algo 2
# I start one distcp that has a blacklist
blacklist = buildBlackList()
hadoop distcp -numListstatusThread 10 -filters blacklist -pct -update /hdfs/root /hdfs/dest

Algo 2는 시작조차하지 않습니다. 소스와 블랙리스트 사이에 diff를 만드는 것이 너무 힘들어 Algo 1을 사용하는 것으로 보입니다.

Oozie 워크 플로에서 모든 워크 플로를 예약해야한다는 것을 알고 있습니다. 내가 distcp 명령어를 많이 가지고 있고 oozie에서 재귀 나 반복을 마스터하지 않기 때문에 쉘 2 액션에 algo 2를 넣었다.

잠시 후에 시작되면 다음 오류가 발생합니다. 컨테이너는 실제 메모리 제한을 초과하여 실행됩니다. 현재 사용량 : 17.2GB의 16GB 실제 메모리 사용

좋아, 그럼 더 많은 기억을 추가 할거야.

<configuration>
    <property>
        <name>oozie.launcher.mapreduce.map.memory.mb</name>
        <value>32768</value>
    </property>
    <property>
        <name>oozie.launcher.mapreduce.map.java.opts</name>
        <value>-Xmx512m</value>
    </property>
</configuration>

그리고 아직도 얻을 수 있습니다 : 컨테이너는 실제 메모리 한계를 넘어서 있습니다. 현재 사용량 : 32.8GB의 32GB 실제 메모리가 사용되었지만 작업이 이전 크기보다 두 배 길었습니다.

클러스터의 RAM이 무한하지 않으므로 더 이상 갈 수 없습니다. 나의 가설은 다음과 같다.

또한, 메모리 관리에 대해 이해하지 못했던 많은 것들이 있습니다. 꽤 안개가 듭니다 (원사, 오지, 비디오, 맵 리듀스).

인터넷 검색을하는 동안, 나는 실제 distcp 사용 사례에 대해 이야기하는 사람이 거의 없다는 것을 알았지 만이 게시물은 4 일 전입니다. https://community.hortonworks.com/articles/71775/managing-hadoop-dr-with-distcp-and-snapshots. html과 내 경우에는 사용할 수없는 스냅 샷 사용법을 설명합니다.

필자는 http://atlas.incubator.apache.org에 대해서도 들었습니다. 결국 파일을 "태그 지정"하고 특정 사용자에게 액세스 권한을 부여함으로써 결국 내 문제를 해결할 수 있었고 특정 위치로 복사하는 것을 피할 수있었습니다. 저의 관리팀에서 작업하고 있습니다.하지만 제작팀에서는이를 알 수 없습니다.

나는 절망적이다. 도와주세요.

해결법

  1. ==============================

    1.YARN 컨테이너는 Linux "cgroups"위에 구축됩니다. 이 "cgroups"는 CPU에 소프트 한도를 적용하는 데 사용되지만 RAM에는 적용되지 않습니다. 따라서 YARN은 서투른 해결 방법을 사용합니다. 각 컨테이너가 사용하는 RAM의 양을 주기적으로 확인하고 할당량을 초과 한 항목을 잔인하게 삭제합니다. 따라서 실행 로그를 잃어 버리고 본 두려운 메시지 만 받게됩니다.

    YARN 컨테이너는 Linux "cgroups"위에 구축됩니다. 이 "cgroups"는 CPU에 소프트 한도를 적용하는 데 사용되지만 RAM에는 적용되지 않습니다. 따라서 YARN은 서투른 해결 방법을 사용합니다. 각 컨테이너가 사용하는 RAM의 양을 주기적으로 확인하고 할당량을 초과 한 항목을 잔인하게 삭제합니다. 따라서 실행 로그를 잃어 버리고 본 두려운 메시지 만 받게됩니다.

    대부분의 경우 JVM 바이너리 (예 : Java / Scala 유틸리티 또는 사용자 정의 프로그램)를 실행 중이므로 자신의 JVM 할당량 (특히 -Xmx)을 설정하여 항상 YARN 한도를 유지할 수 있습니다. 즉, 안전 여유 때문에 일부 RAM을 낭비했다는 의미입니다. 그런데 최악의 경우는 JVM이 메모리가 부족한 상태에서 깨끗하게 실패하는 경우입니다. 실행 로그를 extenso로 가져오고 할당량을 조정하거나 메모리 누수를 수정할 수 있습니다. - /

    그렇다면 귀하의 특정 사건은 어떻게됩니까? Oozie를 사용하여 셸을 시작하면 셸은 hadoop 명령을 시작합니다.이 명령은 JVM에서 실행됩니다. 최대 힙 크기를 설정해야하는 임베디드 JVM에 있습니다. 긴 이야기 짧게 : (oozie.launcher.mapreduce.map.memory.mb를 통해) 쉘을 실행하는 YARN 컨테이너에 32GB를 할당하면 쉘 내의 Java 명령이 28GB 이상을 소비하지 않도록해야합니다 힙 (안전한쪽에 머무르는 것).

    운이 좋으면 단일 env 변수를 설정하면됩니다.

    export HADOOP_OPTS=-Xmx28G
    hadoop distcp ...........
    

    운이 좋다면 hadoop-env.sh의 엉망진창을 다른 env 변수와 섞어서 다른 설정으로 섞어서 풀어야한다. (당신이 알지 못하는 init 스크립트에서 눈에 띄지 않는 사람들이 설정한다.) 복잡한 우선 순위 규칙을 사용하는 JVM 재미있게 보내십시오. 당신은 파기 할 곳에 대한 힌트를 얻기 위해 그 아주 오래된 게시물을 들여다 볼 수 있습니다.

  2. from https://stackoverflow.com/questions/41226242/distcp-container-is-running-beyond-physical-memory-limits by cc-by-sa and MIT license