LabHub
배우기 러닝패스 코스

Apache Hadoop — Stand up and run HDFS and YARN in one pod

Run word count and TeraSort on YARN and read them through counters

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

YARN 을 켜고 책 다섯 편의 낱말을 맵리듀스로 센다. 잡이 끝난 뒤 HDFS 에 남은 잡 이력(.jhist)을 열어 카운터를 읽고, 리듀서 수를 바꿨을 때 출력이 어떻게 나뉘는지, 셔플이 정렬을 어떻게 보장하는지를 TeraSort 로 확인한다.

왜 중요한가

맵리듀스는 요즘 새로 쓰는 일이 드물지만, 그 모델 — 맵이 (키, 값)을 내고, 프레임워크가 키로 모아 정렬해 넘기고(셔플), 리듀스가 키마다 합친다 — 은 Spark·Flink·SQL 엔진의 셔플이 전부 물려받았다. 셔플이 왜 비싼지, 컴바이너(맵 쪽 미리 합치기)가 왜 셔플을 줄이는지, 리듀서 수가 왜 출력 파일 수가 되는지를 여기서 가장 적나라하게 볼 수 있다. 카운터는 잡이 무엇을 했는지를 숫자로 남긴 기록이다. 맵이 몇 줄을 읽고 몇 줄을 냈는지, 컴바이너가 몇 줄로 줄였는지, 리듀스가 키 몇 개를 받았는지. 결과가 이상할 때 가장 먼저 보는 곳이고, 잡이 끝난 뒤에도 이력 파일에 남아 있다. 이 파드의 YARN 은 파드 메모리(2Gi)에 맞춰 컨테이너를 작게 잡아 두었다(AM 384MB, 맵·리듀스 256MB). 그래서 태스크가 한두 개씩 차례로 돈다 — 느려도 결과와 카운터는 같다.

단계

  1. lab-hadoop start yarn 으로 YARN 을 켜고 yarn node -list -all 출력을 /root/hdp/mr/nodes.txt 에 저장하세요.
  2. /data/books/book-*.txt 다섯 편을 HDFS /user/root/mr/in/ 에 올리세요.
  3. 예제 jar 의 wordcount/user/root/mr/in 을 세어 /user/root/mr/wc 에 쓰세요.
  4. 3단계 잡의 ID(job_…)를 /root/hdp/mr/jobid.txt 에 적으세요.
  5. 그 잡의 이력 파일(.jhist)에서 TaskCounter 의 MAP_INPUT_RECORDS·MAP_OUTPUT_RECORDS·COMBINE_INPUT_RECORDS·COMBINE_OUTPUT_RECORDS·REDUCE_INPUT_GROUPS·REDUCE_OUTPUT_RECORDS 를 꺼내 /root/hdp/mr/counters.json 에 쓰세요.
  6. 같은 wordcount 를 리듀서 3개(-D mapreduce.job.reduces=3)로 /user/root/mr/wc3 에 쓰세요.
  7. teragen 으로 10만 줄을 /user/root/mr/tera-in 에 만들고, terasort/user/root/mr/tera-out 에 정렬한 뒤, teravalidate/user/root/mr/tera-val 에 검증 결과를 쓰세요.
  8. /root/hdp/mr/report.md## 맵과 리듀스 ## 카운터 ## 정렬 세 절을 쓰세요. 둘째 절에 5단계의 MAP_OUTPUT_RECORDSCOMBINE_OUTPUT_RECORDS 를 넣으세요.

참고

YARN 켜기

lab-hadoop start yarn 으로 ResourceManager 와 NodeManager 를 켜고, yarn node -list -all 출력을 /root/hdp/mr/nodes.txt 에 저장하세요.

NodeManager 가 ResourceManager 에 자기가 내줄 수 있는 메모리·코어를 알려야 잡을 받을 수 있습니다. 노드가 RUNNING 으로 보여야 합니다. lab-hadoop status 로 JVM 넷(NameNode·DataNode·ResourceManager·NodeManager)이 뜬 것을 확인하세요.

입력 올리기

/data/books/book-1.txt ~ book-5.txt 를 HDFS /user/root/mr/in/ 에 올리세요.

입력 디렉터리 안의 파일마다 입력 조각(split)이 생기고, 조각 하나에 맵 태스크 하나가 붙습니다. 파일 다섯 개는 맵 다섯 개입니다.

wordcount 돌리기

yarn jar /opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.5.0.jar wordcount /user/root/mr/in /user/root/mr/wc 로 낱말을 세세요.

잡이 끝나면 출력 디렉터리에 _SUCCESSpart-r-00000 이 생깁니다. 맵은 낱말마다 (낱말, 1)을 내고, 컴바이너가 맵 쪽에서 먼저 더하고, 리듀서가 낱말마다 합칩니다. 채점기는 여러분의 출력을 원본에서 직접 센 값과 견줍니다.

잡 이력 찾기

3단계 잡의 ID(job_<숫자>_<숫자>)를 /root/hdp/mr/jobid.txt 에 한 줄로 적으세요.

잡을 돌릴 때 콘솔에 'Running job: job_…' 이 찍힙니다. 놓쳤다면 HDFS 의 /tmp/hadoop-yarn/staging/history/done_intermediate/root/ 목록에서 이름에 word+count 가 든 .jhist 를 찾으세요 — 이력 서버 없이도 AM 이 여기에 남깁니다.

카운터 읽기

4단계 잡의 .jhist 에서 org.apache.hadoop.mapreduce.TaskCounter 그룹의 MAP_INPUT_RECORDS·MAP_OUTPUT_RECORDS·COMBINE_INPUT_RECORDS·COMBINE_OUTPUT_RECORDS·REDUCE_INPUT_GROUPS·REDUCE_OUTPUT_RECORDS 를 꺼내 /root/hdp/mr/counters.json{"이름": 정수} 로 쓰세요.

MAP_OUTPUT_RECORDS 는 낱말 수(중복 포함)이고 COMBINE_OUTPUT_RECORDS 는 맵마다 고유 낱말 수의 합입니다 — 셔플로 실제로 넘어간 줄 수입니다. REDUCE_INPUT_GROUPS 는 전체 고유 낱말 수와 같아야 합니다. 두 숫자의 비율이 컴바이너가 아낀 셔플입니다.

리듀서 셋이면 출력도 셋

yarn jar <jar> wordcount -D mapreduce.job.reduces=3 /user/root/mr/in /user/root/mr/wc3 로 리듀서 3개짜리 잡을 돌리세요.

맵 출력은 키의 해시로 리듀서 셋 중 하나에 배정됩니다(HashPartitioner). 그래서 한 낱말은 정확히 한 파일에만 나오고, 각 파일은 그 안에서 정렬되어 있지만 파일끼리는 정렬되어 있지 않습니다.

TeraSort — 셔플이 정렬을 만든다

teragen 100000 /user/root/mr/tera-in 으로 10만 줄(100바이트씩)을 만들고, terasort /user/root/mr/tera-in /user/root/mr/tera-out 으로 정렬한 뒤, teravalidate /user/root/mr/tera-out /user/root/mr/tera-val 로 검증하세요(모두 같은 예제 jar).

TeraSort 는 입력을 표본으로 떠서 키의 범위를 리듀서 수만큼 자르고(전체 순서 분할), 각 리듀서가 자기 범위를 정렬해 내보냅니다. 그러면 출력 파일을 차례로 이어 붙인 것이 전체 정렬이 됩니다. TeraValidate 는 어긋난 곳이 있으면 'misorder' 를, 없으면 체크섬만 씁니다.

셔플을 숫자로 남기기

/root/hdp/mr/report.md## 맵과 리듀스 ## 카운터 ## 정렬 세 절을 쓰세요. 둘째 절에 5단계의 MAP_OUTPUT_RECORDSCOMBINE_OUTPUT_RECORDS 값을 숫자로 넣으세요.

첫 절에는 맵·리듀스가 몇 개였고 출력이 어떻게 나뉘었는지, 둘째 절에는 컴바이너가 셔플을 몇 분의 일로 줄였는지, 셋째 절에는 TeraSort 가 전체 순서를 어떻게 만들었는지를 적으세요.