[데이터엔지니어링] Hadoop HDFS에 대해서 알아보자 - (2편)

Hadoop Distributed File System은 Apache Hadoop의 핵심 스토리지 시스템으로, 대용량 데이터를 분산 저장하고 안정적으로 관리하기 위해 설계된 파일 시스템입니다.

HDFS의 디자인 목표

1. 하드웨어 Failure

HDFS는 파일 시스템의 데이터를 수백, 수천 대의 서버 머신(Node)에 분산하여 저장하는 구조를 갖습니다. 이 때 해당 머신들에서 다양한 장애가 발생할 수 있습니다. (ex : 디스크 장애로 인한 데이터 유실, 네트워크 장애로 인한 접근 불가 등…)

HDFS는 이러한 장애를 빠르게 감지하고 대처할 수 있게 설계 되었습니다. HDFS에 데이터를 저장하면, 복제본도 함께 저장되어 데이터 유실을 방지하고, NameNode와 DataNode 간에는 주기적인 Health Check(Heartbeat)를 통해 장애가 발생한 노드를 빠르게 감지하고 대처할 수 있게 합니다.

2. 스트리밍 데이터 접근

HDFS는 동일한 시간 내에 더 많은 데이터를 처리하는 것을 목표로 합니다. 그래서 User와의 상호작용 보다는 배치 처리를 더 잘 할 수 있도록 설계되었습니다.

HDFS에 저장되는 파일은 여러 개의 대용량 블록(Block) 으로 나뉘어 여러 DataNode에 분산 저장되어 파일 내 특정 위치를 찾는 Random Access 방식에는 적합하지 않습니다. 다만, HDFS는 파일의 처음부터 끝까지 데이터를 순차적으로 읽는 Streaming Access 방식에 최적화되어 있어, 대규모 데이터 분석 작업에서 높은 성능을 발휘할 수 있습니다.

        - Streaming Access: 데이터가 저장된 순서대로 순차적으로 접근. 
        - Random Access: 파일 내 임의의 위치를 지정하여 즉시 접근.

3. 대용량 데이터셋

HDFS는 하나의 파일이 GB~TB 수준의 데이터 크기로 저장될 수 있게 설계되었다.

4. 단순한 일관성 모델

HDFS에서는 파일에 대해 한 번 쓰고(write-once), 여러 번 읽는(read-many) 접근 모델을 필요로 한다.  따라서 한 번 저장한 데이터는 수정할 수 없고, 읽기만 가능하게 하여 데이터 무결성을 지킨다.

5. “연산을 이동하는 것이 데이터를 이동하는 것보다 저렴하다”

애플리케이션이 요청한 연산은, 그 연산이 수행되는 데이터와 가까운 위치에서 실행될수록 효율적이다. 이러한 방식은 네트워크의 혼잡을 줄이고 시스템 전체의 throughput을 높일 수 있다. 그래서 HDFS에서는 Computing 자원을 Data가 있는 위치로 이동시킨다. 

6. 이기종 하드웨어 및 소프트웨어 플랫폼 간의 이식성

HDFS은 쉽게 HW/SW 플랫폼을 옮길 수 있도록 디자인 되었다.

HDFS 아키텍처 - NameNode, DataNode

HDFS는 NameNodeDataNode로 구성됩니다. 간략하게 설명하자면, HDFS는 모든 파일을 일정 크기의 블록으로 나누어 여러  DataNode들에 분산 저장되고, 이때 어떤 파일이 어느 블록에 저장되어 있는지는 Namenode의 메모리에서 메타데이터를 관리합니다

NameNode

역할

- 파일 시스템의 메타데이터(파일의 위치, 권한 등)를 관리.
- 데이터 노드의 리스트를 관리, 유지, 변경.
- 데이터 노드가 전송하는 HeartBeat를 모니터링하여 데이터 노드를 관리.

특징

- 메모리에 모든 메타데이터 유지 → 빠른 접근
- Fsimage와 Edit Log라는 두 종류의 파일로도 메타데이터를 기록
- 단일 장애점(SPOF)이므로 Secondary NameNode 또는 HA 구성 필요

DataNode

역할

- 클라이언트가 HDFS에 저장하는 파일을 디스크에 유지.
- NameNode의 명령에 따라 블록 생성, 삭제, 복제 수행.
- 주기적으로 NameNode에게 HeartBeat 와 블록 리포트(Block들의 리스트와 상태)를 전송.

특징

- 클러스터 내 여러 대의 DataNode로 구성
- 로컬 디스크에 블록 데이터 저장
- 장애 발생 시 자동으로 다른 DataNode에서 복제

HDFS의 데이터 복제

HDFS에서의 파일을 구성하는 각각의 블록은 Fault Tolerance를 위해서 복제됩니다. 이때 각 파일마다 Block Size와 Replication Factor가 지정할 수 있는데,  Replication Factor란 파일의 Replica 수를 의미합니다.

HDFS는 Replica 위치를 최적화하기 위한 규칙을 정의하는데, 이 중에 대표적인 것이 Rack-Awareness 방식입니다.
단히 말하자면 Replica를 같은 랙이 아닌 다른 랙에다가 배치하여, Replica를 전체 랙에 골고루 분산하는 방식입니다.

HDFS 의 Read와 Write

Read 과정

1. 클라이언트가 Distributed FileSystem에 HDFS 파일을 읽겠다는 open() 요청을 보내면

2. 네임노드는 해당 블록을 가진 Datanode들의 위치를 반환한다.

3. Client는 read()메소드를 통해 파일의 첫 번째 블록이 있는 Datanode와 Connection을 맺는다.

4,5. 그렇게 계속 데이터 노드에 파일 블록을 요청한다.

6. end of block에 도달하면 Datanode와의 연결을 끊고 끝낸다.

Write 과정

1. 클라이언트가 NameNode에 파일 생성 요청

2. NameNode가 메타데이터를 생성하고, 블록을 저장할 DataNode를 할당하고 목록을 반환한다.

3. 클라이언트가 첫 번째 DataNode에 데이터 전송

4,5. DataNode들이 파이프라인 방식으로 복제본 전파

6. 모든 복제 완료 후 NameNode에 Write 작업이 끝났음을 알린다.

NameNode HA 구성

그럼 여기까지 들으면서 DataNode 같은 경우에는 확장이 가능하고, 데이터에 대한 복제도 잘 관리한다는 것을 알 수 있습니다.
하지만 NameNode가 하나만 존재할 경우, 해당 NameNode에 장애가 발생하면 전체 HDFS를 사용할 수 없게 되는 단일 지점 장애(SPOF)가 됩니다. 그래서 Namenode를 Active-Standby 구조로 구성하여 SPOF를 제거했습니다.

Active와 Standby Namenode를 각각 두어서 Active NameNode에  문제가 발생하면 Standby Namenode 드가 Active로 동작하게 됩니다. 그러나 장애 발생 여부를 자동으로 판단하는 것은 어렵기 때문에 보통 주키퍼를 이용하여 장애 발생시 자동으로 변경될 수 있도록 합니다. 

장애 발생 시 즉시 전환되기 위해서는 메타데이터의 일관성(Consistency) 이 보장되어야 합니다. Consistency를 유지하기 위해 Active NameNode 와 Standby NameNode는 모두 Datanode로부터 블록 리포트와 하트비트를 받아서 동일한 메타데이터를 유지하고, 공유 스토리지나 저널 노드를 이용하여 Edit Log를 공유합니다.