Data

[Hands On] 도커 기반 하둡 살펴보기 (HDFS, YARN, MapReduce, Hive)

Kaden Sungbin Cho 2021. 1. 27. 21:58
반응형

처음 하둡을 공부하려고 했을 때, 하둡이 무엇이고 정확히는 무엇인지 실체를 알기 어려웠습니다. 더욱 어려웠던 부분은, 책과 이론적인 내용들은 많은 자료가 있었으나 직접 튜토리얼을 진행하고자 하면 HDFS, YARN, MapReduce, Hive 등 다양한 서비스를 설치하고 설정을 연동해야한다는 부분이었습니다.

 

시간이 지나 되돌아보니, 간단한 docker-compose up을 통해 하둡 환경이 로컬에 실행되고 HDFS 네임노드 및 데이터노드의 Web UI를 통해 직접 글로 봤던 사항을 확인해보고 Hive 쿼리를 바로 로컬에서 실행해볼 수 있었으면 더 빨리 배울 수 있었을 것 같다는 생각을 많이 했었습니다.

 

이 글에서는 Big Data Europe에서 제공한 docker-hadoop [1]을 바탕으로 바로 경험해 볼 수 있는 Hands On을 통해 하둡을 설명해보고자 합니다:

 

  • 준비사항
  • docker-compose up 시 생성되는 컨테이너들
  • HDFS
  • YARN
  • Hive & MapReduce

 

 


준비사항

 

docker-compose up 시 생성되는 컨테이너들

먼저, 아래 코드를 실행합니다:

git clone https://github.com/kadensungbincho/de-hands-on.git
cd de-hands-on/docker-hadoop-poc
docker-compose up -d

 

docker-compose up을 실행하게 되면, 도커 이미지가 다운로드 및 빌드 되고 9개의 컨테이너가 생성되게 됩니다:

 

Image from Author

 

 

'docker container ls'와 같은 커맨드를 실행하면 아래와 같이 컨테이너가 생성된 것을 확인할 수 있습니다:

docker container ls
# 출력
... NAMES
... hive-metastore
... hive-server
... namenode
... datanode
... docker-hadoop-poc_zookeeper_1
... hive-metastore-mysql
... nodemanager
... historyserver
... resourcemanage

 

 

HDFS

HDFS는 하둡분산파일시스템(Hadoop Distributed File System)으로 네임노드 그리고 데이터노드로 구성되어 하나의 파일을 블록으로 쪼개고, 블록들을 여러 노드에 나누어 저장합니다. 

 

UI 확인

먼저, http://localhost:9870/ 에 접속하면 아래와 같은 UI를 확인할 수 있습니다.

 

Namenode UI - Image from Author

위의 UI 첫 페이지에서는 하둡 버젼, 설정된 파일시스템의 수용량(Capacity), 네임노드의 힙 및 논힙 메모리 사용량, 파일 및 디렉토리 그리고 블록 갯수, active 데이터노드 갯수 등을 확인할 수 있습니다. 

 

 

Tab 'Datanodes' - Image from Author

2번째 'Datanodes' 탭을 클릭하면 현재 active한 데이터노드들의 상태를 자세히 확인할 수 있습니다. 현재는 아키텍쳐의 이미지와 같이 1개의 데이터노드가 실행되고 있습니다. http address는 데이터노드가 실행되고 있는 컨테이너의 호스트명이 'e441708a840d'라서 http://e441708a840d:9864 로 보이고 있습니다.

 

실제로는 http://localhost:9864를 통해 아래와 같이 해당 데이터노드의 UI에 접근할 수 있습니다.

Datanode UI - Image from Author

 

HDFS 커맨드 실행해보기

HDFS는 분산파일시스템 관리를 위해 다양한 커맨드를 제공합니다. 위의 도커 기반의 환경에서 기본적인 HDFS 커맨드를 실행해보며 그 동작방식을 살펴보겠습니다.

 

docker exec -it namenode bash
# 컨테이너 안
jps
# 출력
771 Jps
374 NameNode

먼저 위와 같이 네임노드가 실행되고 있는 컨테이너에 들어가 jps 커맨드를 통해 네임노드를 확인할 수 있습니다. 

 

hdfs dfs -ls /
# output
Found 3 items
drwxr-xr-x   - root supergroup          0 2021-02-16 12:47 /rmstate
drwxrwxr-x   - root supergroup          0 2021-02-16 12:47 /tmp
drwxr-xr-x   - root supergroup          0 2021-02-16 12:47 /user

'hdfs dfs -ls /'를 통해 루트 path의 파일 및 디렉토리를 리스트업할 수 있습니다. 

 

touch tmp.txt
hdfs dfs -put tmp.txt /tmp
hdfs dfs -ls /tmp
# output
drwx-wx-wx   - root supergroup          0 2021-02-21 02:37 /tmp/hive
-rw-r--r--   3 root supergroup          0 2021-02-21 02:42 /tmp/tmp.txt

'hdfs dfs -put <파일명> <put할 path>'을 통해 로컬 파일시스템의 파일을 HDFS의 분산파일시스템에 업로드할 수 있습니다. 

 

rm tmp.txt
hdfs dfs -get /tmp/tmp.txt
ls
# output
... tmp.txt

또한, 'hdfs dfs -get <파일명>'을 통해 분산파일시스템 상의 파일을 로컬로 가져올 수도 있습니다. 

 

실제 분산파일시스템 상의 데이터는 데이터노드가 위치한 노드의 로컬 파일시스템의 특정 path에 저장됩니다. 그 파일을 살펴보기 위해서는 먼저 아래와 같이 데이터노드의 설정을 확인해야 합니다:

docker logs datanode
# output
// ...
  - Setting dfs.datanode.data.dir=file:///hadoop/dfs/data
// ...

실행 시 쉘 스크립트는 위와 같은 환경변수를 읽어서 hdfs-site.xml에 넣어주고 있습니다. 이 hdfs-site.xml은 아래와 같이 확인해볼 수 있습니다:

 

docker exec -it datanode bash

# in container
cat /opt/hadoop-3.2.1/etc/hadoop/hdfs-site.xml

# output
// ...
<property><name>dfs.datanode.data.dir</name><value>file:///hadoop/dfs/data</value></property>
// ...

그렇기에 분산파일시스템에 파일을 쓰고, 데이터노드 안에서 '/hadoop/dfs/data'라는 위치를 확인해보면 아래와 같이 파일이 존재하는 것을 확인할 수 있습니다:

 

# in datanode
 echo "kadencho" >> tmp1.txt
 hdfs dfs -put tmp1.txt /user/kaden
 hdfs dfs -ls /user/kaden
 
# output
drwxr-xr-x   - kaden hadoop          0 2021-02-21 02:36 /user/kaden/.Trash
-rw-r--r--   3 root  hadoop          9 2021-02-21 02:55 /user/kaden/tmp1.txt

# check local file system
cat /hadoop/dfs/data/current/BP-1701142848-172.21.0.5-1613874948639/current/finalized/subdir0/subdir0/blk_1073741831

# output
kadencho

 

YARN

먼저, http://localhost:8088/cluster에서 아래와 같은 UI를 확인할 수 있습니다.

YARN UI - Image from Author

클러스터의 노드, 애플리케이션, 스케쥴러 등 리소스매니저의 전반적인 정보를 제공합니다. 애플리케이션 정보의 경우 분리되어 있는 애플리케이션히스토리서버(타임라인 서버로 이름 변경)에서 가져오는 것을 확인할 수 있습니다 (http://localhost:8188). 

 

Hive & MapReduce

마지막으로, Hive를 통해 MapReduce 애플리케이션을 실행하고, YARN의 UI에서 확인해보도록 하겠습니다. 

 

docker exec -it hive-server bash

# in container
hive

# in hive console
show databases;

# output
OK
default
tmp
Time taken: 0.884 seconds, Fetched: 2 row(s)

위와 같이 현재 default와 tmp라는 2개의 데이터베이스가 Hive에 등록되어 있는 것을 알 수 있습니다. 

 

use tmp;
show tables;

# output
OK
daily_employee
hourly_employee
Time taken: 0.038 seconds, Fetched: 2 row(s)

select * from daily_employee;

# output
OK
3	Sungbin	10000	Sinsa	20191010
4	Bob	20000	NewYork	20191010
1	Kaden	10000	Seoul	20191011
2	Barney	20000	Berlin	20191011
Time taken: 2.676 seconds, Fetched: 4 row(s)

위와 같이 tmp.daily_employee라는 테이블에 4개의 행이 존재하는 것을 확인할 수 있습니다. 이후 아래와 같이 sum을 하는 쿼리를 실행하고 YARN UI에서 해당 애플리케이션에 대한 정보를 확인할 수 있습니다:

SELECT SUM(salary) FROM daily_employee;

# output
// ...
2021-02-21 04:48:21,419 Stage-1 map = 0%,  reduce = 0%
2021-02-21 04:48:27,694 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 1.83 sec
2021-02-21 04:48:34,900 Stage-1 map = 100%,  reduce = 100%, Cumulative CPU 3.78 sec
MapReduce Total cumulative CPU time: 3 seconds 780 msec
Ended Job = job_1613881676137_0005
MapReduce Jobs Launched: 
Stage-Stage-1: Map: 1  Reduce: 1   Cumulative CPU: 3.78 sec   HDFS Read: 9627 HDFS Write: 107 SUCCESS
Total MapReduce CPU Time Spent: 3 seconds 780 msec
OK
60000.0
Time taken: 26.142 seconds, Fetched: 1 row(s)

YARN UI - Image from Author

 

 

Reference

[1] github.com/big-data-europe/docker-hadoop

반응형