하둡 프로그래밍 - HDFS

Park Suyong·2021년 1월 27일
1

하둡

목록 보기
3/8
post-custom-banner

1. HDFS란

HDFS는 하둡에서 사용하는 분산 파일 시스템이다. HDFS 이전에도 다음과 같은 대용량 파일 시스템이 존재했다.

  • DAS(Direct-Attached Storage)
    서버에 직접 연결된 스토리지(storage)이며, 외장형 하드 디스크라고 생각하면 된다. 여러 개의 하드 디스크를 장착할 수 있는 외장 케이스를 이용하는 방식이다.
  • NAS(Network-Attached Storage)
    일종의 파일 서버이다. 별도의 운영체제를 사용하며, 파일 시스템을 안정적으로 공유할 수 있다. 주로 첨부 파일이나 이미지 같은 데이터를 저장하는 데 많이 사용한다.
  • SAN(Storage Area Network)
    수십에서 수백 대의 SAN 스토리지를 데이터 서버에 연결해 총괄적으로 관리해주는 네트워크를 말한다. DAS의 단점을 극복하기 위해 개발됐고, 현재 SAN 기법이 굉장히 많이 사용되고 있다. DBMS와 같이 안정적이고 빠른 접근이 필요한 데이터를 저장하는 데 사용한다.

HDFS와 기존 대용량 파일 시스템의 가장 큰 차이점은 Commodity Hardware로 구축할 수 있다는 것이다. 이로써 상당한 비용 감축 효과를 볼 수 있다. 일반적인 대용량 파일 시스템을 구축하기 위해서는 상당히 고성능의 서버를 사용해야 하기 때문이다.

물론, HDFS가 기존 대용량 파일 시스템을 완전히 대체하는 것은 아니다. DBMS 처럼 고가용성이 필요한 경우 SAN을 사용하며, 안정적인 파일 저장이 필요한 경우 NAS를 사용한다. 또한, 트랜잭션이 중요한 경우 HDFS를 사용하지 않는다. 대규모 파일 저장배치 처리(Batch Processing)가 필요한 경우 HDFS를 사용한다.

1-1. HDFS의 디자인 철학, 목표

  • 장애 복구
    HDFS는 여러 많은 노드, 즉 컴퓨터로 구성된다. 따라서, 다양한 장애가 발생할 수 있다. 가령 해당 컴퓨터의 로컬 디스크에 문제가 생겨 데이터 저장이 실패할 수도 있고 디스크 복구가 불가능한 경우 데이터를 아예 유실할 수도 있는 심각한 문제가 발생할 수 있다. 또한, 네트워크에 문제가 발생하는 경우 특정 서버에 대한 네트워크가 차단될 수도 있다.
    HDFS는 이러한 장애를 복구할 수 있게, 대처할 수 있게 설계되어 있다. HDFS에 데이터를 저장하면 블록 단위로 데이터를 나눠서 여러 노드에 저장하여 데이터 유실을 방지하고, 서버 간에 상태를 체크하여 빠른 시간 내에 장애를 확인하고 복구할 수 있도록 한다.

  • 스트리밍 방식의 데이터 접근
    HDFS는 클라이언트의 요청을 빠른 시간 내에 처리하는 것보다 동일 시간 내에 더 많은 데이터를 처리하는 것에 중점을 둔다. 따라서, HDFS는 랜덤 방식의 데이터 접근을 사용하지 않는다. 그러므로 실시간 처리가 중요한 금융 등에서는 이를 사용하지 않는다.
    HDFS는 랜덤 접근 방식 대신 스트리밍 방식으로 데이터에 접근한다. 따라서, 클라이언트는 끊김 없이 데이터에 접근할 수 있다.

  • 대용량 데이터 저장
    HDFS는 하나의 대용량 파일을 잘 저장할 수 있게 설계됐다.

  • 데이터 무결성
    HDFS는 한번 저장한 데이터는 수정할 수 없고, 읽기와 append 하는 기능만 제공한다. 이로써 데이터의 무결성을 유지한다. 다만, 데이터의 이동, 삭제, 복사할 수 있는 인터페이스를 제공한다.

2. HDFS Architecture

HDFS는 블록 구조의 파일 시스템이다. 데이터를 저장하면 기본 64MB 단위의 블록으로 데이터를 쪼개서 데이터를 저장한다. 이 때 하나의 블록은 기본적으로 3개씩 복제되어 HDFS에 저장된다. 여러 개의 블록은 각각 다른 노드에 분산되어 저장되므로 로컬 서버의 하드 디스크보다 더 큰 규모의 데이터를 저장할 수 있는 것이다. 그렇다면 블록의 크기가 왜 64MB일까? 참고로, 하둡 2.0 부터는 기본 블록의 크기가 128MB이다.

  • 디스크 seek time의 감소
    HDFS는 디스크 seek time이 디스크 전송 대역폭의 1%만을 사용하는 것을 목표로 했으므로 100MB에 근접한 64MB를 사용하는 것이다.

  • 네임 노드가 유지하는 메타 데이터의 크기 감소
    네임 노드는 HDFS에 저장되는 파일에 대한 메타 데이터를 갖고 있다. 만약 데이터 블록의 기본 저장 단위가 64MB보다 더 작다면, 네임 노드에 저장되는 메타 데이터가 더욱 늘어나게 될 것이다. 그런데 메타 데이터는 네임 노드의 메모리에 저장된다. 따라서, 네임 노드의 메모리 용량에 따라 저장될 수 있는 데이터의 양이 영향을 받게 된다. 하지만 하둡은 Commodity Hardware로 구축할 수 있는 클러스터 환경을 추구하므로 메타 데이터의 수를 줄일 수 있다면 좋을 것이다.

  • 클라이언트와 네임 노드의 통신 감소
    클라이언트가 HDFS에 저장된 파일에 접근하려면 네임 노드에서 우선 데이터 블록의 위치를 조회하게 된다. 하나의 파일은 HDFS에서 여러 데이터 블록으로 나눠지게 되는데, 데이터 블록의 단위가 낮다면 네임 노드에서 더 많은 블록을 조회해야 해서 더 많은 통신이 발생하게 될 것이다. 또한, 클라이언트는 스트리밍 방식으로 데이터를 읽고 쓰기 때문에 특별한 경우를 제외하고는 네임 노드와 통신할 필요가 없을 것이다.

하둡은 기본적으로 master-slaves architecture 이다. HDFS의 경우 네임 노드가 Master, 데이터 노드가 Slave이다. MapReduce의 경우 JobTracker가 Master, TaskTracker가 Slave이다. 참고로, 하둡2.0 이상의 YARN 구조에서는 JobTracker, TaskTracker 없이 Resource Manager, Node Manager가 각각 master-slaves 구조로 동작하게 된다.
그렇다면 Namenode의 역할에 대해 알아보자.

  • 메타 데이터 관리
    네임 노드는 파일 시스템을 유지하기 위한 메타 데이터를 관리한다. 메타 데이터는 파일에 대한 정보가 포함되어 있는 데이터이다. 네임 노드는 메타 데이터를 메모리에 로드하여 사용한다.

  • 데이터 노드 모니터링
    데이터 노드는 네임 노드에게 3초에 한 번씩 Heartbeats message를 전송하게 된다. 이는 데이터 노드가 네임 노드에게 본인이 살아있음을 알리는 것이고, 이 메시지에 데이터 노드의 상태 정보와 Block Report를 넣어 보내게 된다. Block Report는 데이터 노드에 저장되어 있는 블록의 목록이다.

  • 블록 관리
    네임 노드는 다양한 방법을 사용하여 블록을 관리하게 된다. 네임 노드가 장애가 발생한 데이터 노드를 발견하게 되면 해당 데이터 노드의 블록들을 새로운 데이터 노드로 복제한다. 또한, 용량이 부족한 데이터 노드가 있다면 용량에 여유가 있는 데이터 노드로 블록을 이동시킨다. 마지막으로 네임 노드는 블록의 복제본 수도 관리한다. 어쩌다가 정해진 블록의 수보다 적거나 많아진다면 이를 조정하게 된다.

  • 클라이언트 요청 접수
    클라이언트가 HDFS에 접근하기 위해서는 반드시 네임 노드에 먼저 접속해야 한다. 네임 노드는 클라이언트의 목적에 맞게 데이터를 쓰거나 읽도록 도와주게 된다.

Datanode의 역할은 간단하다. 클라이언트가 HDFS에 저장하는 데이터를 데이터 노드에서는 이를 로컬 디스크에 저장한다. 이 때 로컬 디스크에 저장되는 파일은 실제 데이터가 저장되어 있는 로우 데이터체크섬이나 파일 생성 일자 같은 메타 데이터가 설정되어 있는 파일 총 2개를 저장한다.

2-1. HDFS의 파일 저장

HDFS의 파일 저장은 여러 단계로 이루어진다.
먼저, 클라이언트가 네임 노드에게 파일 저장을 요청한다. 그 다음 클라이언트가 데이터 노드에게 패킷을 전송하고 마지막으로 클라이언트가 파일 저장을 완료하게 된다. 이러한 단계들에 대해 알아보도록 한다.

1. 파일 저장 요청

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

2. 패킷 전송

클라이언트가 네임 노드에게서 파일 제어권을 얻게 되면 파일 저장을 진행한다. 이 때 클라이언트는 파일을 네임 노드에게 전송하는 것이 아니라 데이터 노드에게 전송하게 된다. 저장하게 될 파일은 패킷 단위로 쪼개어 전송하게 된다.

3. 파일 닫기

스트림을 닫고 파일 저장을 완료하는 단계이다.

2-2. HDFS의 파일 읽기

1. 파일 조회 요청

클라이언트는 입력 스트림 객체를 이용해 HDFS에 저장된 파일을 조회할 수 있다. 클라이언트가 입력 스트림 객체를 생성한다.

2. 블록 조회

클라이언트가 블록을 조회한다. 네임 노드가 클라이언트에게 가까운 순으로 정렬된 블록 위치 목록을 반환하게 된다.

3. 입력 스트림 닫기

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

2-3 보조 네임 노드 (Secondary Name Node)

네임 노드는 메모리에 메타 데이터를 로드하여 관리한다. 다만, 모든 데이터를 메모리에 로드해 관리하게 될 경우 서버를 재부팅했을 때 모든 데이터가 유실될 수 있다. 이러한 문제를 예방하기 위해 HDFS는 editslogfsimage라는 파일을 생성한다.

editslog는 HDFS의 모든 변경 이력을 저장한다. HDFS는 클라이언트가 파일을 저장, 삭제, 이동하는 경우 editslog와 메타 데이터에 모두 기록한다. fsimage는 메모리에 저장된 메타 데이터의 파일 시스템 이미지를 저장한 것이다. 네임 노드가 구동되는 경우 editslog, fsimage를 사용하게 된다.

우선적으로 fsimage를 메모리에 로딩해 파일 시스템 이미지를 생성한다. 그 다음 메모리에 로딩된 팡리 시스템 이미지에 editslog에 기록된 파일 변경 이력을 적용한다. 그 다음 적용된 상태에서 fsimage 파일을 갱신하고, editslog를 초기화한다.

이 방법은 평소엔 아무 문제가 없으나, editslog의 크기가 커질 경우 문제가 된다. 이 파일은 무한대로 커질 수 있기 때문이다. 따라서, 크기가 크다면 메모리에 로딩된 파일 시스템 이미지에 editslog를 적용하는 과정이 오래 걸리게 될 것이다.

이러한 문제점을 해결하기 위해 HDFS는 보조 네임 노드(Secondary Name Node)를 사용한다. 보조 네임 노드는 주기적으로 네임 노드의 fsimage를 갱신하는데, 이를 체크 포인트(Check Point)라고 한다. 그래서 흔히 보조 네임 노드를 체크 포인팅 서버(check pointing server)이라고도 한다. 체크 포인팅은 1시간마다 한 번씩 일어나며 하둡 환경설정 파일에서 fs.checkpoint.period 속성값을 수정해 이를 제어할 수 있다.

보조 네임 노드는 네임 노드의 백업 서버가 아니다. 보조 네임 노드는 네임 노드의 fsimage를 주기적으로 갱신해 줌으로써 크기를 축소시켜 주는 역할을 수행할 뿐이다.

profile
Android Developer
post-custom-banner

0개의 댓글