설치

하둡은 java기반이라 java sdk설치가 필요.

sudo apt-get update
sudo apt-get install default-jdk

그다음, 도커 이미지 받아서 그 안에서 연습해볼수도 있지만, 제대로 하려면 아래처럼 다운받고 설정하는 과정이 필요

# 하둡의 공식 웹사이트에서 최신 버전을 다운받아 설치
sudo wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz

# 압축풀고 설정진행
tar -xvf hadoop-3.3.0.tar.gz
sudo mv hadoop-3.3.0 /usr/local/hadoop
#~/.bashrc에 아래 것들 추가
export HADOOP_HOME=/usr/local/hadoop
export PATH=$PATH:$HADOOP_HOME/bin
export PATH=$PATH:$HADOOP_HOME/sbin
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64


#반영
source ~/.bashrc

그다음 어떤 파일시스템을 하부로 쓸것인지 설정파일들을 좀 만져야함. 기본으로 깔렸을때는 hdfs가 아닌 로컬파일시스템을 쓰도록 되어 있음(;;)

# sudo vi $HADOOP_HOME/etc/hadoop/core-site.xml
# <configuration> 태그 사이에 아래내용 추가
<property>
    <name>fs.defaultFS</name>
    <value>hdfs://localhost:9000</value><!--이거 해줘야 로컬파일시스템이 아닌 hdfs씀-->
</property>

# sudo vi $HADOOP_HOME/etc/hadoop/hdfs-site.xml
# <configuration> 태그 사이에 아래내용 추가

<property>
    <name>dfs.replication</name>
    <value>1</value> <!--HDFS에 저장되는 각 데이터 블록이 클러스터 전체에서 복제되는 횟수를 결정-->
</property>

단일노드가 아닌 클러스터 구성시 추가 설정들이 필요(여기서는 생략)

 

다음은 포맷하고 전체시작

# 처음에 포맷해줘야 함
hdfs namenode -format

#전체 재시작
cd /usr/local/hadoop/sin
./stop-all.sh
./start-all.sh

#java ps. 아래처럼 NameNode, DataNode, SecondaryNameNode가 뜨는것을 확인
jps
128290 SecondaryNameNode
127865 NameNode
128026 DataNode

 

HDFS기본 핸들링 방법

아래처럼 hdfs dfs로 시작하는 명령을 주거나,  Hadoop이 제공하는 Hadoop FUSE(FIlesystem in USErspace) 모듈을 이용하면 기존파일시스템에 mount해서 ls,mv,cp등 그대로 사용하는 것도 가능

# /logs라는 폴더 만들기
hdfs dfs -mkdir /logs

# ls하기. Hadoop Distributed File System (HDFS)의 루트 디렉토리 내용을 나열
hadoop dfs -ls /
Found 1 items
drwxr-xr-x   - sevity supergroup          0 2023-07-29 13:20 /logs

# 파일 복사하기.
hdfs dfs -put iis_logs/* /logs

# 헬스체크
hdfs fsck /

 

 

트러블슈팅

기본적인 로그 모니터링

tail -f /usr/local/hadoop/logs/*.log

start-dfs.sh로 하둡을 시작했을때 namenode가 시작되지 않았을때(jps했을때 안보일때)

# 아래 명령으로 이유 파악
 grep -C 5 'ERROR' $HADOOP_HOME/logs/hadoop-sevity-namenode-sevityubuntu.log

# 만약 아래처럼 /tmp 아래 디렉토리 접근이 안된다는 것이면
2023-07-30 16:03:30,469 ERROR org.apache.hadoop.hdfs.server.namenode.NameNode: Failed to start namenode.
org.apache.hadoop.hdfs.server.common.InconsistentFSStateException: Directory /tmp/hadoop-sevity/dfs/name is in an inconsistent state: storage directory does not exist or is not accessible.
        at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverStorageDirs(FSImage.java:392)

# hdfs-site.xml을 열어서 경로를 /tmp가 아닌 /var/lib등 임시가 아닌곳으로 옮겨준다.
vi /usr/local/hadoop/etc/hadoop/hdfs-site.xml
아래 내용 추가
    <property>
      <name>dfs.namenode.name.dir</name>
      <value>/var/lib/hadoop-hdfs/cache/hdfs/dfs/name</value>
    </property>

# 관련 폴더 만들고 권한 부여
sudo mkdir -p /var/lib/hadoop-hdfs/cache/hdfs/dfs/name
sudo chown -R sevity:sevity /var/lib/hadoop-hdfs/cache/hdfs/dfs/name

# 아래명령어로 다시 실행
stop-dfs.sh
start-dfs.sh

datanode가 시작되지 않을때

# jps 했는데 datanode관련된게 안보이면
grep -C 5 "ERROR" $HADOOP_HOME/logs/hadoop-*-datanode-*.log
# 아래와 같은 로그면
2023-07-30 16:24:23,819 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for Block pool <registering> (Datanode Uuid 6b5e2ab5-f8a4-4eb8-b3d3-fe37de728e60) service to localhost/127.0.0.1:9000. Exiting.

# 다음처럼 /hadoop/data 안에 있는 데이터를 날려준다(데이터 포맷은 각오)
rm -rf /hadoop/data/*

부팅할때마다 hdfs 구동되도록 하기(기본적으로는 항상 start-dfs.sh로 시작해줘야함)

sudo vi /etc/systemd/system/hadoop-hdfs.service # 해서 아래내용 입력
[Unit]
Description=Hadoop HDFS
After=network.target

[Service]
User=sevity
Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
ExecStart=/usr/local/hadoop/sbin/start-dfs.sh
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

# 그 다음 다음을 입력해서 systemctl 리로딩하고, enable을 통해서 부팅시마다 시작되도록 함
sudo systemctl daemon-reload
sudo systemctl enable hadoop-hdfs

# 재부팅해서 jps해서 다음처럼 namenode, datanode, SecondaryNameNode 3가지 띁거 확인
jps
4673 SecondaryNameNode
3929 NameNode
4255 DataNode

# 마지막으로 헬스체크
hdfs fsck /

 

 

 

 

병렬처리 관련 중요 포인트

mapper가 병렬처리되는것으로 보이나 reducer는 모든 mapper가 끝나야 작업을 시작할 수 있나?
네, 맞습니다. MapReduce 모델에서 Mapper와 Reducer의 작업은 서로 다른 단계에 속하며, 이는 병렬 처리와 데이터 의존성 문제 때문입니다.
Mapper: 각 Mapper는 독립적으로 입력 데이터의 한 부분을 처리하며, 그 결과를 키-값 쌍의 형태로 출력합니다. 이 과정은 병렬로 진행될 수 있으며, 여러 컴퓨터 또는 프로세서 코어에서 동시에 일어날 수 있습니다.
Shuffle and Sort: Mapper의 출력은 모든 Reducer에게 보내지기 전에 "Shuffle and Sort" 단계를 거칩니다. 이 단계에서는 동일한 키를 가진 모든 데이터를 같은 Reducer로 라우팅하고, 키에 대한 데이터를 정렬합니다.
Reducer: Reducer는 키별로 그룹화된 데이터를 받아 처리합니다. 이 과정에서 Reducer는 자신에게 할당된 특정 키에 대한 모든 데이터를 받아야만 작업을 시작할 수 있습니다. 이는 각 키에 대한 모든 값들이 Reducer에서 합쳐지거나 처리되어야 하기 때문입니다. 따라서 Reducer는 모든 Mapper의 작업이 끝나야만 시작됩니다.
이와 같은 방식은 분산 환경에서 대규모 데이터를 처리하는 데 효율적인 방법을 제공합니다. Mapper는 독립적으로 실행되므로 컴퓨터 클러스터의 모든 머신을 활용할 수 있습니다. Reducer는 특정 키에 대한 모든 데이터를 처리하므로, 결과를 재결합하거나 요약하는 작업을 처리할 수 있습니다. 이 모델의 중요한 특성 중 하나는 개발자가 병렬 처리에 대한 세부 사항을 걱정할 필요가 없다는 것입니다. 이는 MapReduce 프레임워크가 처리하기 때문입니다.

반응형

+ Recent posts