~$ 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를 고정시키도록 한다.
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으로 사용할 수 있도록 수정한다.
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
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 pythonimport sys
value = 1for line in sys.stdin:
line = line.strip()
words = line.split()
for word in words:
print(f'{word}\t{value}')
- reducer.py
#!/usr/bin/env pythonimport sys
word_last = None
word_count = 0for 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과 같은 결과
댓글