1. Apache Hadoop

하둡이 탄생하게 된 배경은 하나의 머신에서 저장하고 처리가 불가능한 크기의 데이터(빅 데이터)를 여러 대의 컴퓨터에 분산 저장 및 처리 할 수 있는 시스템을 만들고자 태어난 시스템이다.

하둡은 대규모 분산 컴퓨팅의 파일 시스템에 빅데이터를 분할(Distribute) 저장 후, 분할된 데이터를 Key-Value방식을 이용하여 병렬처리를 수행하고 빠른 속도로 데이터 처리를 할 수 있는 시스템이다.

1.1 MapReduce, 맴리듀스

하둡은 데이터의 일부분이 저장된 클러스터의 각 머신에서 맵리듀스 프로그램을 시작한다. 이렇게 하면 데이터의 지역성을 확보할 수 있다. 이를 위해 하둡은 YARN이라 불리는 하둡 자원 관리 시스템을 이용한다.

1.2 HDFS, 하둡 분산 파일시스템

파일시스템이란 컴퓨터에서 파일이나 데이터를 손쉽게 탐색 및 접근을 할 수 있도록 보관 또는 조직화하는 체제를 말한다.

네트워크로 연결된 여러 머신의 스토리지를 관리하는 파일시스템을 분산 파일시스템이라고 한다. 하둡은 데이터를 저장할 때 데이터를 분할한 후에 분산하여 저장한다.

1.2.1 HDFS 설계

HDFS는 범용 하드웨어로 구성된 클러스터에서 실행되고 스트리밍 방식의 데이터 접근 패턴으로 대용량 파일을 다룰 수 있도록 설계된 파일시스템이다.

1.2.2 HDFS 개념

3.2.2.1 블록(Block)

물리적인 디스크는 블록 크기라는 개념을 가지고 있다. 블록 크기는 한번에 읽고 쓸 수 있는 데이터의 최대량을 말한다. HDFS의 블록 크기는 기본적으로 128MB이고, HDFS의 파일은 단일 디스크를 위한 파일시스템처럼 특정 블록 크기의 청크로 쪼개지고 각 청크는 독립적으로 저장된다.

블록은 단지 저장된 데이터의 청크일 뿐이고 권한 정보와 같은 파일의 메타데이터는 블록과 함께 저장될 필요가 없으므로 별도의 시스템에서 다루도록 분리할 수 있다.

블록은 내고장성과 가용성을 제공하는데 필요한 복제(Replication)를 구현할 때 매우 적합하다.

3.2.2.1 파일저장방식

HDFS 클러스터는 마스터-워커 패턴으로 동작하는 두 종류의 노드로 마스터인 하나의 네임노드(NameNode)와 워커인 여러 개의 데이터노드(DataNode)로 구성된다.

파일의 구성은 메타데이터(MetaData)와 컨텐츠데이터로 구성된다. 파일의 메타데이터는 네임노드의 메모리에 저장한다. 그렇기 때문에 네임노드의 메모리 크기에 따라서 저장할 수 있는 파일의 최대 수가 결정된다. 파일, 디렉토리, 블록은 각각 150byte 정도의 메모리가 필요하다.

컨텐트 데이터는 블록의 크기에 맞게 쪼개서 데이터노드에 분산해서 저장한다.

3.2.2.3 블록 캐싱

데이터노드는 데이터를 디스크에 저장된 블록을 읽는다. 하지만 빈번하게 접근하는 블록 파일은 오프-힙(Off-Heap, 자바 힙 외부에서 관리되는) 블록 캐시(Block cache)라는 데이터노드의 메모리에 명시적으로 캐싱 될 수 있다.

기본적으로 블록은 하나의 데이터노드 메모리에만 캐싱되잠 파일 단위로 설정할 수 있다. 잡스케줄러(맴리듀스, 스파크)는 블록이 캐싱된 데이터노드에서 테스크가 실행되도록 할 수 있으며, 이러한 블록 캐시의 장점을 이용하면 읽기 성능을 높일 수 있다.

사용자나 애플리케이션은 캐시 풀(Cache Pool)에 캐시 지시자를 추가하여 특정 파일을 캐싱하도록 명령할 수 있다.

3.2.2.4 HDFS Federation(연합체)

네임노드는 파일시스템의 모든 파일과 각 블록에 대한 참조 정보를 메모리에 관리한다. 그래서 노드 확장 시, 메모리 문제가 발생한다. 이러한 이유로 페더레이션을 지원하게 되었다.

페더레이션을 활용하면 각각의 네임노드가 파일시스템의 네임스페이스 일부를 나누어 관리하는 방식으로 새로운 네임노드를 추가할 수 있다. 예를 들어, 하나의 네임노드는 /user 디렉토리 아래의 모든 파일을 관리하고 다른 네임노드는 /share 디렉토리 아래의 모든 파일을 관리한다.

이렇게 페더레이션을 적용하면 각 네임노드는 네임스페이스의 메타데이터를 구성하는 네임스페이스 볼륨(Namespace Volumn)과 네임스페이스에 포함된 파일의 전체 블록을 보관하는 블록 풀(Block poll)을 관리한다.

네임스페이스 불륨은 각각의 네임노드에서 관리한다. 그렇기 때문에 서로 통신을 할 필요가 없지만, 파일의 전체 블록을 관리하는 블록 풀의 저장소는 공통으로 사용하게 된다. 그렇기 때문에 하나의 네임노드가 문제가 발생하면 해당하는 네임노드가 관리하는 네임스페이스에만 문제가 생긴다.

3.2.2.4 HDFS 고가용성(HA, High Availability)

고가용성은 활성대기(active-standby) 상태로 설정된 한 쌍의 네임노드로 구현된다. Active Namenode에 장애가 발생하면 Standby Namenode가 그 역할을 이어받아 큰 중단 없이 클라이언트의 요청을 처리한다. 이러한 방식을 지원하기 위해 HDFS의 구조를 일부 변경했다.

  1. 네임노드는 에디트 로그를 공유하기 위해 고가용성 공유 스토리지를 반드시 사용해야 한다. standby namenode가 active 상태로 변경되면 가장 먼저 active namenode의 상태를 동기화하기 위해 공유 에디트 로그를 읽고, 이어서 기존 active namenode에 새로 추가된 항목도 마저 읽는다.
  2. Datanode는 블록 리포트(Block Report)를 두 개의 네임노드에 보내야 한다. 블록 매핑 정보는 디스크가 아닌 네임노드의 메모리에 보관되기 때문이다.
  3. Active Name Node는 Journal Node의 Edit log에 쓰기(Write) 권한을 가지고 있지만, Standby Name Node는 읽기(Read) 권한만 있다.

고가용성 공유 스토리지를 위해 NFS 필러나 QJM(Quorum Jouranl Manager) 중 하나를 선택할 수 있다. QJM은 HDFS 전용 구현체로, 고가용성 에디트 로그를 지원하기 위한 목적으로 설계 됐다.

QJM은 저널노드 그룹에서 동작하며, 각 에디트 로그는 전체 저널 노드에 동시에 쓰여진다. 일반적으로 저널 노드는 세 개며, 그중 하나가 손상되어도 문제가 없는 시스템이다.

장애복구와 펜싱

Standby Namenode를 Active Namenode로 활상화 시키는 전환 작업은 장애복구 컨트롤러(Failover Controller)라는 새로운 객체로 관리된다. 장애복구 컨트롤러의 구현은 단 하나의 네임노드만 활성 상태에 있는 것을 보장하기 위해서 주키퍼(Zookeeper)를 이용한다.

각 네임노드는 경량의 장애복구 컨트롤러 프로세스로 네임노드의 장애를 감시하고(Heartbeat 방식 사용) 네임노드에 장애가 발생하면 장애복구를 지시한다.

장애가 발생한 네임노드(Active)가 어떠한 장애 발생으로 실행이 되지 않고 있다고 판단하기가 어렵다. 예를 들어 네트워크가 느려지거나 단절되어 장애복구를 위한 전환 작업이 시작된 상황에서도 기존의 네임노드는 여전히 실행되고 있고 자신이 Active 네임노드라고 생각 할 것이다. 그렇기 때문에 기존의 활성화 네임노드가 시스템을 손상시키지 않게 조심해야 한다. 그래서 QJM은 펜싱이라는 메서드를 제공한다.

QJM은 한 번에 하나의 네임노드만 에디트 로그를 쓸 수 있도록 보장한다. 하지만 기존의 활성네임노드가 클라이언트의 읽기 요청에 대해 잘못된 정보를 줄 가능성이 있으므로 SSH 펜싱 명령어로 네임노드의 프로세스를 확실히 죽이도록 설정하는 것이 가장 좋다.

Active Name node에 장애가 발생하게 되면 펜싱로직이 수행된다. 펜싱로직이 정상적으로 수행되면 Standby Name node가 Active Name node로 전환되는 작업이 수행된다.

1.3 YARN(Resource Manager)

1.3.1 유용한 CMD

2. Apache Hadoop Install Guide

2.1 Hadoop 설정파일

2.1.1 하둡 설정파일 종류

경로 : $HADOOP_HOME/etc/hadoop

  1. core-site.xml

    <configuration>
    	<property>
    	  <name>hadoop.tmp.dir</name>
    		<value>/usr/local/Cellar/hadoop/hdfs/tmp</value>
    		<description>A base for other temporary directories.</description>
      </property>
    	<property>
    		<name>fs.fs.default.name</name>
    		<value>hdfs://${HOSTNAME}:9000</value>
    	</property>
    </configuration>
    
  2. hdfs-site.xml