Hadoop 1-1 ~ 1-3

1부에서는 설치와 HDFS의 기본 이론을 위주로 공부합니다.
1-1에서는 하둡에 대한 설명했고 1-2에서는 설치에 대한 설명을 했습니다.
모두 각설하고 1-3인 하둡 분산 파일 시스템에 대해 공부하겠습니다.

우선 HDFS란 무엇인가부터 알아보겠습니다.
HDFS란?
수십 테라바이트 또는 페타바이트 이상의 대용량 파일을 분산된 서버에 저장하고, 많은 클라이언트가 저장된 데이터를 빠르게 처리할 수 있게 설게된 파일 시스템입니다.

3.1 HDFS 기초 

HDFS 이전에도 DAS, NAS, SAN 과 같은 대용량 파일 시스템이 있었으며, HDFS 또한 이러한 대용량 파일 시스템과 유사점이 많습니다.

DAS ( Direct - Attached Storage ) : 서버에 직접 연결된 스토리지이며, 외장형 하드디스크로 이해하면 됩니다.

NAS ( Network - Attached Storage ) : 일종의 파일 서버입니다. 별도의 운영체제를 사용하며, 안정적으로 공유할 수 있습니다.

SAN ( Storage Area Network ) : 수십대에서 수백대의 SAN 스토리지를 데이터 서버에 연결해 총괄적으로 관리해주는 네트워크를 의미합니다.

HDFS와 위 3가지 스토리지와의 가장 큰 차이점은 저사양 서버를 이용해 스토리지를 구성할 수 있다는 것입니다. HDFS 에 저장ㄷ하는 데이터는 물리적으로 분산된 서버의 로컬 디스크에 저장돼있지만, 파일의 읽기 및 저장과 같은 제어는 HDFS에서 제공하는 API를 이용해 처리됩니다.

HDFS는 네 가지 목표를 가지고 설계됐습니다.
1. 장애 복구
2. 스트리밍 방식의 데이터 접근
3. 대용량 데이터 저장
4. 데이터 무결성


3.2 HDFS 아키텍처

1. 블록 구조 파일 시스템

HDFS는 블록 구조의 파일 시스템입니다. HDFS에 저장하는 파일은 특정 크기의 블록으로 나눠져 분산된 서버에 저장됩니다. 블록 크기는 기본적으로 64MB로 설정돼 있으며, 변경 가능 합니다.

그렇다면 왜 하필 64MB나 되는 걸까요?

1-1. 디스크 시크 타임의 감소입니다. 디스크의 탐색 시간은 데이터 위치를 찾는 데 걸리는 시간인 시크타임과 원하는 데이터의 섹터에 도달하는 데 걸리는 시간인 서치타임의 합입니다.

1-2. 네임노드가 유지하는 메타데이터의 크기 감소입니다. 네임 노드는 블록 위치, 파일명, 디렉터리 구조, 권한 정보와 같은 메타 데이터정보를 메모리에 저장하고 관리합니다.

1-3. 클라이언트와 네임노드의 통신 감소입니다. 클라이언트가 HDFS에 저장된 파일을 접근할 때 네임노드에서 해당 파일을 구성하는 블록의 위치를 조회합니다.



2. 네임 노드와 데이터 노드

HDFS는 마스티-슬레이브 아키텍쳐입니다. 


네임 노드
HDFS의 마스터 서버인 네임노드는 다음과 같은 기능을 수행합니다.

* 메타데이터 관리
* 데이터노드 모니터링
* 블록 관리
* 클라이언트 요청 접수

데이터 노드
데이터 노드는 클라이언트가 HDFS에 저장하는 파일을 로컬 디스크에 유지합니다. 이때 로컬 디스크에 저장되는 파일은 두 종류로 구성됩니다. 로우 데이터와 메타 데이터가 저장됩니다.

3. HDFS의 파일 저장

HDFS의 파일 저장은 클라이언트가 네임노드에게 파일 저장을 요청하는 단계, 클라이언트가 데이터노드에게 패킷을 전송하는 단계, 클라이언트가 파일 저장을 완료하는 단계로 구성됩니다. 이번에는 파일 저장의 단계별 세부 동작 방식을 알아보겠습니다. 

파일 저장 요청
클라이언트가 HDFS에 파일을 저장하는 경우 파일을 저장하기 위한 스트림을 생성해야 합니다. 


패킷 전송
클라이언트가 네임노드에게서 파일 제어권을 얻게 되면 파일 저장을 진행합니다. 이 때 클라이언트는 파일을 네임노드에게 전송하지 않고 각 데이터 노드에 전송합니다.


파일 닫기
이제 스트림을 닫고 파일 저장을 완료할 차례입니다. 



4.  HDFS의 파일 읽기

이번에는 HDFS에 저장된 파일을 조회하는 과정을 단계별로 알아보겠습니다.

1. 파일 조회 요청 : 클라이언트는 스트림을 요청하고 분산 파일 시스템은 스트림을 생성합니다. 클라이언트 JVM 안에 있는 DFS 클라이언트가 네임 노드에게 블록 위치를 요청하고 반환 받습니다.

2. 블록 조회 : 클라이언트에서 네임노드와 데이터 노드에게 블록 조회를 요청한 뒤 블록 위치 목록을 반환 받습니다. 

3. 입력 스트림 닫기 : 클라이언트가 모든 블록을 읽고 나면 입력 스트림 객체를 닫아야 합니다. 

5. 보조 네임 노드

앞서 네임노드는 메타데이터를 메모리에서 처리한다고 설명했습니다. 하지만 메모리에만 데이터를 유지할 경우 서버가 재부팅될 경우 모든 메타데이터가 유실될 수 있습니다. HDFS는 이러한 문제점을 극복하기 위해 EDITSLOG 와 FSIMAGE라는 두 개의 파일을 생성합니다.

EDITLOGS는 HDFS의 모든 변경 이력을 저장합니다. 
FSIMAGE는 메모리에 저장된 메타데이터의 파일 시스템 이미지를 저장한 파일입니다.
다음과 같은 단계로 위 두 개의 파일을 사용합니다. 

1. 네임노드가 구동되면 로컬에 저장된 FSIMAGE와 EDITLOG를 조회합니다.
2. 메모리에 FSIMAGE를 로딩해 파일 시스템 이미지를 생성합니다.
3. 메모리에 로딩된 파일 시스템 이미지에 EDITLOG에 기록된 변경 이력을 적용합니다.
4. 메모리에 로딩된 파일 시스템이미지를 이용해 FSIMAGE파일을 갱신합니다.
5. EDITLOG를 초기화합니다.
6. 데이터 노드가 전송한 블록리포트를 메모리에 로딩된 파일 시스템 이미지에 적용합니다.

EDITLOG의 크기가 클 경우 문제를 야기할 수 있기 때문에 보조네임노드라는 노드를 제공합니다. 보조네임노드는 주기적으로 네임노드의 FSIMAGE를 갱신하는 역할을 하며, 이러한 작업을 체크포인트라고 합니다. 그래서 흔히 체크 포인팅 서버라고 표현하기도 합니다.



체크 포인팅이 완료되면 네임노드의 FSIMAGE는 최신 내역으로 갱신되며, EDITLOG의 크기도 축소됩니다. 참고로 체크 포인팅은 1시간마다 한 번씩 일어납니다.

하둡을 처음 접한 독자는 보조네임노드를 중요치 않게 생각할 수 있습니다. 또한 백업 서버라고 생각할 수도 있습니다. 앞서 설명했듯이 보조네임노드는 FSIMAGE 파일을 축소시켜주는 역할을 담당할 뿐 백업 서버가 아닙니다. 

보조네임노드가 정상적으로 구동되지 않아도 큰 문제가 없어 보이기 때문에 그냥 넘어갈 수도 있습니다. 하지만 FSIMAGE 파일이 점점 커지고 메모리에 로딩하지 못하는 상황이 되면 문제가 되기 때문에 그 전에 보조네임노드의 정상적인 구동을 확인하시기 바랍니다.


3.5 HDFS 입출력 예제

3.3인 하둡 명령어와 3.4인 클러스터 웹 인터페이스는 넘어가도록 하겠습니다.
여기서 예제를 공부해보기 전에 이 책에서는 자바 프로그래밍에 대한 기초 지식이 있다는 전제하에 예제를 실행합니다. 그래서 저도 자바 실행에서 한참 해멨던 기억이 있습니다.
아래 사이트의 도움이 굉장히 컸습니다. 
하둡 이클립스 환경 설정에 대한 정보를 올려주셨습니다.
http://blog.acronym.co.kr/333

환경 설정을 맞췄다면 아래의 코드를 분석해보겠습니다.

''' java
package wikibooks.hadoop.chapter03;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class SingleFileWriteRead {
  public static void main(String[] args) {
    // 입력 파라미터 확인
    if (args.length != 2) {
      System.err.println("Usage: SingleFileWriteRead ");
      System.exit(2);
    }

    try {
      // 파일 시스템 제어 객체 생성
      Configuration conf = new Configuration();
      FileSystem hdfs = FileSystem.get(conf);

      // 경로 체크
      Path path = new Path(args[0]);
      if (hdfs.exists(path)) {
        hdfs.delete(path, true);
      }

      // 파일 저장
      FSDataOutputStream outStream = hdfs.create(path);
      outStream.writeUTF(args[1]); // 문자열 쓰기
      outStream.close();

      // 파일 출력
      FSDataInputStream inputStream = hdfs.open(path);
      String inputString = inputStream.readUTF();
      inputStream.close();

      System.out.println("Input Data:" + inputString);

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
'''

이제 하둡에서 실행하겠습니다. 다음과 같이 jar 옵션을 이용해 빌드한 jar 파일을 실행합니다.

$./bin/hadoop jar hadoop.jar wikibooks.hadoop.chapter03.SingleFileWriteRead input.txt Hello,HDFS

첫 번째 파라미터는 input.txt 이고, 두 번째 파라미터는 Hello,HDFS 이다.
Fs shell의 ls 명령어로 조회하면 input.txt. 파일이 출력됩니다.

아직 하둡의 핵심인 맵리듀스는 시작도 못했습니다. 아직 이론과 간단한 예제만 알아보았습니다. 다음엔 맵리듀스를 공부하겠습니다.

Reference : 시작하세요! 하둡 프로그래밍 -위키북스-

댓글

이 블로그의 인기 게시물

윈도우 설치에서 파티션 설정 오류(NTFS)

[exploit writing] 1_스택 기반 오버플로우 (1) First

하둡 설치 오류 정리