HDFS 아키텍처

HDFS 아키텍처

HDFS(Hadoop Distributed File System)는 값싼 범용 하드웨어 위에서 도는 분산 파일 시스템이에요. 수십 GB짜리 파일을 블록 단위로 쪼개 여러 대의 노드에 나눠 저장하고, 하드웨어 고장이 일어나도 데이터를 잃지 않도록 설계됐죠. 이 글에서는 네임노드와 데이터노드가 어떻게 협력하고, 데이터가 어떻게 복제·조직되는지 큰 그림부터 하나씩 살펴볼게요.

출처: HDFS Architecture (공식문서)

본문

설계 목표

HDFS는 처음부터 지금의 목적에 맞춰 설계됐는데요, 그 핵심 가정들을 먼저 보는 게 구조를 이해하는 데 도움이 돼요.

  • 하드웨어 장애(Hardware Failure): 수천 대의 노드가 있으면 매 순간 어딘가는 망가지기 마련이에요. HDFS는 장애를 예외가 아니라 정상적인 상황으로 보고, 이를 감지하고 자동으로 복구하는 것을 목표로 해요.
  • 스트리밍 데이터 접근(Streaming Data Access): 대화형 처리보다 높은 처리량(high throughput) 을 우선해요. 수 ms 응답보다 보통 몇 분 혹은 몇 시간에 걸쳐 대용량 데이터셋을 순차로 읽는 배치 워크로드에 맞춰져 있어요.
  • 대용량 데이터셋(Large Data Sets): 파일 하나가 수백 MB에서 수 TB에 이를 수 있어요. HDFS는 이렇게 큰 파일을 수만 대의 노드에 걸쳐 담을 수 있도록 설계됐죠.
  • 단순 일관성 모델(Simple Coherency Model): 파일은 한 번 쓰면 여러 번 읽는(write-once-read-many) 방식이에요. 만든 뒤에는 끝에 붙이기(append)나 잘라내기(truncate)만 가능하고 중간을 고칠 수 없어요. 이 덕분에 데이터 일관성 문제가 단순해지고 처리량을 높일 수 있어요.
  • 계산을 데이터로 이동: "계산을 움직이는 것보다 데이터를 움직이는 게 더 비싸요(Moving Computation is Cheaper than Moving Data)". 데이터가 있는 노드로 계산을 보내는 편이 네트워크를 훨씬 덜 쓰기 때문이에요.
  • 이기종 호환성: GNU/Linux가 흔하지만 그 외 OS에서도 MySQL과 함께 자주 쓰이듯, 다양한 하드웨어·소프트웨어 플랫폼에서 돌 수 있게 만들어졌어요.

네임노드와 데이터노드

HDFS는 마스터-워커 구조를 띠는데요. 네임노드(NameNode)는 파일 시스템의 메타데이터(어떤 파일이 어디에, 몇 조각으로 나뉘어 있는지)를 관리하는 마스터이고, 데이터노드(DataNode)는 실제 데이터 블록을 저장하는 워커예요.

  • 네임노드(NameNode): 클러스터에 딱 하나 있는 마스터로, 파일시스템 네임스페이스(어떤 파일/디렉터리가 있는지)와 클라이언트의 파일 접근을 관리해요. 모든 블록의 위치를 알고 있죠.
  • 데이터노드(DataNode): 실제 데이터 블록을 저장하고, 읽기·쓰기 요청에 응답하며, 주기적으로 하트비트(Heartbeat)블록 리포트(Blockreport) 를 네임노드에 보내요.

데이터 복제(Data Replication)

네임노드는 블록의 복제본이 어디에 몇 개 있을지를 모두 결정해요. 데이터노드들이 보내는 하트비트를 받아 노드가 정상인지 확인하고, 블록 리포트를 받아 그 노드가 가진 모든 블록 목록을 알게 되죠. 기본적으로 파일 블록 하나의 복제본을 여러 개(보통 데이터노드 3개) 두어 하드웨어 장애에도 데이터를 보존해요.

블록 복제본 배치는 랙 인식(Rack Awareness) 을 따르는데요, 서로 다른 랙에 복제본을 나눠서 어느 한 랙 전체가 죽는 사고에도 데이터가 남도록 만드는 전략을 취해요.

  • 안전 모드(Safemode): 네임노드가 시작할 때 블록 리포트가 충분히 모이기 전까지는 쓰기 연산을 막는 유지보수용 상태예요. 이때 블록이 손상됐거나 복제본이 부족하면 안전 모드에서 나오면서 복제를 다시 만들어요.

파일 시스템 메타데이터의 영속화

네임노드는 메타데이터를 영속 상태로 관리해요. fsimage는 네임스페이스의 마지막 체크포인트(스냅샷)이고, edits는 그 이후 일어난 변경 사항을 기록한 저널이에요. 네임노드가 시작하면 fsimage를 읽고 edits를 적용해 최신 상태를 만든 다음, 다시 fsimage를 갱신하고 비운 edits로 시작해요.

클러스터가 바빠 edits가 계속 커지면 다음 재시작이 느려지니까, 실행 중에도 Secondary NameNodeCheckpoint Node가 주기적으로 fsimage와 edits를 병합해 edits 크기를 일정 한도 안으로 유지해줘요.

견고성(Robustness)

HDFS는 데이터 무결성을 지키기 위해 체크섬(checksum) 을 써요. 클라이언트가 파일을 만들 때 블록마다 체크섬을 계산해 같은 네임스페이스의 별도 숨김 파일에 저장하고, 읽을 때는 받은 데이터가 저장된 체크섬과 일치하는지 검증해요. 저장 장치 결함이나 네트워크 오류로 데이터가 손상됐다면 검증에서 걸러지죠.

데이터 조직: 블록

HDFS에서 파일은 기본적으로 128MB 블록으로 쪼개져요. 즉, 파일 하나가 여러 128MB 조각으로 잘리고, 가능하면 각 조각이 서로 다른 데이터노드에 놓이게 돼요. 복제 파이프라이닝(Replication Pipelining)으로 클라이언트가 첫 데이터노드에 쓴 데이터가 두 번째, 세 번째 노드로 순차 전달되면서 복제본이 만들어져요.

접근성

HDFS는 기본적으로 Java 기반의 FileSystem API로 접근하고, 그 위에 셸 명령과 관리 명령을 제공해요.

FS Shell 예시:

  • 디렉터리 만들기: bin/hadoop fs -mkdir /foodir
  • 파일 내용 보기: bin/hadoop fs -cat /foodir/myfile.txt
  • 디렉터리 삭제: bin/hadoop fs -rm -R /foodir

DFSAdmin 예시:

  • 클러스터를 안전 모드로: bin/hdfs dfsadmin -safemode enter
  • 데이터노드 목록 확인: bin/hdfs dfsadmin -report
  • 데이터노드 재구성·페기: bin/hdfs dfsadmin -refreshNodes

공간 회수

삭제된 파일은 기본적으로 휴지통(Trash) 에 보관됐다가 일정 시간 뒤 완전히 사라져요. 완전히 지우고 싶다면 -skipTrash 옵션을 써요.

$ hadoop fs -rm -r -skipTrash delete/test2
Deleted delete/test2

복제 인자(replication factor)를 줄이면 네임노드가 삭제할 여분의 복제본을 고르고, 다음 하트비트가 그 정보를 데이터노드에 전달해서 해당 블록이 제거돼요.

더 알아보기