LabHub
배우기 러닝패스 코스

Apache Hadoop — 1つのPodにHDFSとYARNを立てて運用する

単語カウントと TeraSort を YARN に載せ、カウンタで読む

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 가 전체 순서를 어떻게 만들었는지를 적으세요.