목표
VM 환경에서 하둡을 완전 분산 모드로 설치하고 Map-Reduce를 실행해보자.
준비
- Java 8
- SSH
- Hadoop-3.3.1
기본설치
- 필요한 패키지 정보 업데이트
~$ sudo apt update
~$ sudo apt upgrade -y
- Java 8 설치
~$ sudo apt install openjdk-8-jdk -y
# 버전 확인
~$ java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (build 1.8.0_292-8u292-b10-0ubuntu1~20.04-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)
- SSH 설치
~$ sudo apt install ssh -y
~$ ssh localhost
# yes 입력 시 다음부터 비밀번호 계속 입력할 필요 없음
? yes
password: 로그인 시 입력했던 비밀번호
# exit를 통해 ssh 연결 끊음
~$ exit
- Hadoop 다운로드
~$ wget https://archive.apache.org/dist/hadoop/common/hadoop-3.3.1/hadoop-3.3.1.tar.gz
# 압축 해제
~$ tar -xzf hadoop-3.3.1.tar.gz
# 폴더명 변경
~$ mv hadoop-3.3.1 hadoop
- ~/.bashrc 수정
~$ nano ~/.bashrc
# java jdk 설치 경로
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
# hadoop 설치 경로
export HADOOP_HOME=/home/hadoop/hadoop
# PATH 설정을 통해 해당 경로로 이동하거나 경로를 입력하지 않아도 실행 가능
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:
# 이후 python으로 mapreduce 진행할 때 hadoop streaming 사용
# 경로는 find /home/hadoop -name hadoop-streaming* 으로 찾을 수 있음
export HADOOP_STREAMING=$HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-3.3.1.jar
# [Ctrl + X] + Enter 로 저장하고 나옴.
source ~/.bashrc
추가 설정
Hadoop은 Master - Slave 구조로 이루어져 있고, 통신을 하기 위해서는 IP 주소가 필요하다.
하지만 IP는 255^4 개로 제한되어 있어서 사용하지 않는 IP는 회수하고 이후에 다시 할당받게 되는데, 이 과정에서 IP가 변하게 된다. 매번 번거로운 작업을 하지 않기 위해서 VM 내에서 서로 통신을 할 수 있도록 IP를 고정시키도록 한다.
참고: 네트워크 가상화 모드 (https://technote.kr/213)
Slave 생성(복제) 및 IP 고정
- 먼저 실행된 VM을 종료한다.
- VirtualBox 도구 우측의 메뉴에서 네트워크 클릭.
- VirtualBox Host-Only Ethernet Adapter가 만들어져 있으면 클릭해서 속성을 수정함.
- 어댑터 탭 -> 수동으로 어댑터 설정(M)
- DHCP 서버 탭 -> 서버 사용함(E) 체크 - 복제할 VM을 우클릭 하고 복제를 클릭,
- 적절한 이름을 입력하고 [MAC 주소 정책(P) -> 모든 네트워크 어댑터의 새 MAC 주소 생성] 설정 후 [다음(N)]. [완전한 복제(F)] 선택 후 [복제].
- (4~5 를 한번 더 반복함).
- VM-master부터 모든 slave에 대해 진행함.
7.1. VM 우클릭 - 설정 7.2. 네트워크 - 어댑터1(NAT) - 어댑터2
- [네트워크 어댑터 사용하기(E) - 다음에 연결됨(A)(호스트 전용 어댑터) - 위에서 생성한 어댑터 선택 - 무작위 모드(P)(모두 허용) - 확인]
- 그리고 여기서 가장 아래에 MAC 주소를 기억해둔다.
- 각각의 VM을 모두 실행시키고 터미널 실행[Ctrl + Alt + T]
~$ ip addr # 아마도 3번까지의 주소가 나올텐데, # 여기서 link/ether 옆에 아까 확인한 MAC 주소와 같은 주소가 적혀있는 부분의 IP 주소를 확인하면 된다. ex) 3: enp0s8: < ... link/ether xx:xx:xx:xx:xx:xx brd ff:... inet 192.168.x.x ... ... # inet 부분이 IP 주소이다.
hostname, /etc/hosts 수정
매번 IP 주소를 사용하기 번거롭기 때문에 이를 hostname으로 사용할 수 있도록 수정한다.
- hostname 변경
# VM - master
~$ hostnamectl set-hostname master
~$ sudo reboot
# VM - slave1
~$ hostnamectl set-hostname slave1
~$ sudo reboot
# VM - slave2
~$ hostnamectl set-hostname slave2
~$ sudo reboot
- /etc/hosts 수정
hadoop@master:~$ sudo nano /etc/hosts
# ** 모든 node에서 수정 ** #
# x.x.x.x localhost
# x.x.x.x hadoop-VirtualBox
# 아래에
# 123.123.123.3 master
# 123.123.123.4 slave1
# 123.123.123.5 slave2
# 와 같이 추가하고 [Ctrl + x] - y - 엔터
# 이제 IP 주소가 아닌 hostname으로 접속 가능.
hadoop@master:~$ ssh slave1
> yes
> 비밀번호
# 사용자가 slave1로 바뀐것을 확인할 수 있음.
hadoop@slave1:~$ exit
# 다시 접속해도 비밀번호를 입력해야 함.
hadoop@master:~$ ssh slave1
> 비밀번호
암호 없이 접속하기
- 암호가 없는 ssh 접속을 위해서 master의 공개키를 생성해서 이를 각 slave의 인증된 키로 보내주어야함.
hadoop@master:~$ ssh-keygen -t rsa -f ~/.ssh/id_rsa
# 엔터
# authorized_keys에 공개키 추가
hadoop@master:~$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# 권한 변경
hadoop@master:~$ chmod 0600 ~/.ssh/authorized_keys
# slave로 키 복사
hadoop@master:~$ ssh-copy-id -i /home/hadoop/.ssh/id_rsa.pub slave1
hadoop@master:~$ ssh-copy-id -i /home/hadoop/.ssh/id_rsa.pub slave2
# 계속 연결 할 것인지 물어보면 > yes
# password 입력
hadoop@master:~$ ssh slave1
hadoop@slave1:~$ exit
하둡 세팅
- 세팅해야 할 파일들이 있는 위치로 이동
- master 에서 실행
cd $HADOOP_HOME/etc/hadoop
# or
# cd /home/hadoop/hadoop/etc/hadoop
- core-site.xml
# nano or vi or vim 아무거나 사용가능
vim core-site.xml
# <configuration> 안에 입력
<property>
<name>fs.defaultFS</name>
<value>hdfs://master:9000</value>
</property>
- hdfs-site.xml
vim hdfs-site.xml
# <configuration> 안에 입력
# namenode 데이터 경로 설정
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/hadoop/data/namenode</value>
</property>
# datanode 데이터 경로 설정
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/hadoop/data/datanode</value>
</property>
# data 복제 갯수 설정 (장애 대응)
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
# secondary namenode 설정
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>slave1:50090</value>
</property>
- yarn-site.xml
vim yarn-site.xml
# <configuration> 안에 입력
<property>
<name>yarn.resourcemanager.hostname</name>
<value>master</value>
</property>
# log 출력
<property>
<name>yarn.log-aggregation-enables</name>
<value>true</value>
</property>
- mapred-site.xml
vim mapred-site.xml
# <configuration> 안에 입력
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>yarn.app.mapreduce.am.env</name>
<value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
</property>
<property>
<name>mapreduce.map.env</name>
<value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
</property>
<property>
<name>mapreduce.reduce.env</name>
<value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value>
</property>
- hadoop-env.sh
vim hadoop-env.sh
# / 누르고 export JAVA_HOME 검색, #을 지우고 아래로 수정
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
- workers
vim workers
# 모두 지우고
slave1
slave2
# 입력 후 저장
- slave에 복사
scp $HADOOP_HOME/etc/hadoop/* slave1:$HADOOP_HOME/etc/hadoop/
scp $HADOOP_HOME/etc/hadoop/* slave2:$HADOOP_HOME/etc/hadoop/
하둡 실행
# namenode foramt
hdfs namenode -format
# 하둡 실행
start-dfs.sh
start-yarn.sh
hadoop@master:~/hadoop$ jps
5752 ResourceManager
5449 NameNode
6031 Jps
# slave1에는 세컨더리 네임노드가 있음
hadoop@slave1:~/hadoop$ jps
3360 Jps
3234 NodeManager
2931 DataNode
3059 SecondaryNameNode
hadoop@slave2:~/hadoop$ jps
2880 Jps
2757 NodeManager
2533 DataNode
- hdfs 저장소
hadoop@master:~/hadoop$ hdfs dfs -ls
ls: '.': No such file or directory
# 디렉토리가 없으므로 /user, /user/wordcount directory 생성
hadoop@master:~/hadoop$ hdfs dfs -mkdir -p /user/wordcount
# README.txt를 hdfs /user/wordcount에 저장
hadoop@master:~/hadoop$ hdfs dfs -put $HADOOP_HOME/README.txt /user/wordcount
hadoop@master:~/hadoop$ hdfs dfs -ls /user/wordcount
Found 1 items
~ ~ ~
Map Reduce 예제 실행해보기
Map-Reduce는 mapper와 reducer로 이루어져 있고, 어떤 파일을 열고 파싱을 통해 key-value값을 reducer로 전달, reducer에서는 key-value 값을 일정한 규칙에 따라 정리함.
cd $HADOOP_HOME
find . -name *mapreduce-example*
~
./share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar
~
~
# hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar
# 를 입력하면 사용할 수 있는 예제들이 나옴.
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.1.jar \
wordcount \
/user/wordcount/README.txt \
/user/wordcount/example0
...
# 결과 확인
hdfs dfs -text /user/wordcount/example0/*
Mapper / Reducer 구현 - Python
sudo apt-get install python-is-python3
- mapper.py
#!/usr/bin/env python
import sys
value = 1
for line in sys.stdin:
line = line.strip()
words = line.split()
for word in words:
print(f'{word}\t{value}')
- reducer.py
#!/usr/bin/env python
import sys
word_last = None
word_count = 0
for line in sys.stdin:
line = line.strip()
key, value = line.split('\t', 1)
value = int(value)
if word_last == key:
word_count += value
else:
if word_last:
print(f'{word_last}\t{word_count}')
word_last = key
word_count = value
if word_last == key:
print(f'{word_last}\t{word_count}')
- 실행
hadoop jar $HADOOP_STREAMING \
-input /user/wordcount/README.txt \
-output /user/wordcount/example00 \
-file $HADOOP_HOME/code/mapper.py -mapper mapper.py \
-file $HADOOP_HOME/code/reducer.py -reducer reducer.py
hdfs dfs -text /user/wordcount/example00/*
# mapreduce-example과 같은 결과
'DATA SCIENCE > HADOOP ECOSYSTEMS' 카테고리의 다른 글
Hadoop 3 완전 분산 모드 설치 - 1 (VirtualBox에 Linux 설치하기) (0) | 2021.10.31 |
---|---|
[Hbase] Hbase ? (0) | 2021.10.13 |
댓글