HDFS
Hadoop Distributed File System의 약자로, 하둡에서 대용량 데이터를 저장하고 관리하기 위해 설계된 분산 파일 시스템이다.
간단히 말하면, HDFS는 여러 대의 컴퓨터(노드)들에 데이터를 나눠 저장하는 시스템이다.
HDFS의 주요 특징
1. 데이터 분산 저장
- HDFS는 데이터를 여러 조각으로 나눠서 여러 컴퓨터(노드)에 저장한다. 예를 들어, 1GB 크기의 파일을 128MB씩 나눠서 8개의 블록으로 쪼개고, 각각의 블록을 서로 다른 노드에 저장한다.
2. 데이터 복제
- HDFS는 데이터를 안전하게 보관하기 위해 복사본을 만든다. 보통 한 데이터 블록의 복제본이 최소 3개의 다른 노드에 저장된다. 이렇게 하면 한 노드에 문제가 생기더라도 데이터를 잃지 않고 복구할 수 있다.
3. 고장 감내성
- HDFS는 하드웨어나 네트워크에 문제가 생겨도 시스템 전체가 멈추지 않고 계속 동작할 수 있도록 설계됐다. 데이터가 복제돼 있기 때문에, 특정 노드가 고장 나더라도 다른 노드에서 데이터를 사용할 수 있다. 주기적으로 서버의 상태를 점검해 장애를 빠르게 감지하고 대응한다.
4. 스트리밍 데이터 접근
- HDFS는 빠른 데이터 처리에 중점을 두며, 실시간 요청보다는 한 번에 큰 데이터 처리를 목표로 한다. 파일 시스템처럼 무작위로 데이터를 읽고 쓰는 방식(Random Access)을 지원하지 않으며, 데이터를 순차적으로 스트리밍 방식으로 접근하기 때문에 대규모 배치 처리에 적합하다.
HDFS Architecture
Block based file system
Block-based file system은 데이터를 작은 조각들(블록)로 나눠 저장하는 파일 시스템을 의미한다.
HDFS에서는 큰 파일을 직접 통째로 저장하지 않는다. 대신 파일을 일정 크기의 여러 개의 작은 조각, 즉 블록(block)으로 나누고 이 블록들은 서로 다른 서버(노드)에 분산돼 저장된다.
왜 이렇게 나눌까?
- 효율성: 파일을 여러 블록으로 나누면, 여러 서버가 동시에 이 블록들을 처리할 수 있어 데이터 처리속도가 빨라진다. (=병렬 처리)
- 안전성: 블록으로 나눈 데이터는 여러 서버에 복제본을 만들어 저장하기 때문에, 한 서버에 문제가 생기더라도 다른 서버에 저장된 블록을 사용해 데이터를 복구할 수 있다.
- 확장성: HDFS는 데이터를 여러 서버(노드)에 나눠 저장하기 때문에, 데이터가 늘어나면 서버를 추가하는 방식으로 저장 용량을 쉽게 확장할 수 있다. 예를 들어, 작은 박스 하나(노드)에 넣을 수 없는 물건(데이터)를 여러 박스(노드)에 나눠 담는것 같다. 이렇게 하면 개별 박스(노드)의 크기를 넘는 물건(데이터)도 보관할 수 있다.
파일과 블록
1. 파일을 블록으로 나눔: 하나의 파일은 하나 또는 여러 개의 블록으로 나눠져 저장된다. 이 때, 어떤 파일이 어느 블록에 저장됐는지는 메타데이터로 namenode가 메모리에서 관리한다. (예를 들어, 128MB 블록으로 설정된 HDFS에서 1000MB 파일은 128MB 블록 7개와 10 4MB 블록 하나로 나뉘어 저장된다.)
2. 블록과 파일의 관계: 하나의 파일은 여러 블록에 나눠 저장될 수 있지만, 하나의 블록에는 여러 파일이 들어갈 수 없다. 만약 파일 크기가 블록 크기를 초과하지 않으면, 파일 전체가 하나의 블록에 저장된다. (예를 들어, 1MB 파일은 128MB 블록 하나에 저장되지만, 실제로 차지하는 공간은 1MB이다.)
3. 블록 크기보다 작은 파일: 블록이 크더라도, 파일이 작으면 해당 파일이 차지하는 공간만큼만 실제로 디스크에 저장된다. (예를 들어, 1MB 파일이 128MB 블록에 저장되면, 실제로 사용되는 디스크 공간은 1MB이다.)
Block System의 장점
1. 디스크 탐색 시간 감소
: HDFS는 블록 크기를 적절하게 설정해(64MB, 128MB) 디스크 탐색 시간을 최소화한다. 큰 블록 크기는 탐색 시간에 비해 데이터를 전송하는 시간을 더 많이 사용하게 되어, 디스크 성능을 최적화한다. 즉, 데이터를 여러 번 찾느라 시간을 낭비하는 대신, 한 번에 더 많은 데이터를 가져오는 데 시간을 쓰는 것이 효율적이다.
2. 메타데이터 크기 감소
: 블록 크기를 크게 설정하면, 네임노드가 관리해야 할 메타 데이터의 양이 줄어든다. 예를 들어, 200MB 파일이 128MB 블록 2개로 저장되면 메타데이터도 2개만 필요하다. 작은 블록 크기라면 더 많은 메타데이터가 필요해 네임노드의 부담이 커질 수 있다.
3. 클라이언트와 네임노드 간의 통신 비용 절감
- 큰 블록 크기는 클라이언트가 파일을 접근할 때 네임노드와 통신을 최소화한다. 작은 블록 크기라면 많은 블록 위치를 조회해야 하므로, 통신 횟수가 증가할 수 있다.
위 내용만 보면 블록 크기를 무조건 크게하는 것이 좋아 보이지만, 실제로는 작은 파일이 있을 때 블록 공간이 낭비된다.
예를 들어, 1MB 파일을 128MB 블록에 저장하면, 1MB만 사용되고 나머지 127MB는 비어있어 디스크 공간을 비효율적으로 사용하게 된다.
즉, 파일 크기와 작업 특성에 맞는 적절한 블록 크기를 설정해야 한다.
NameNode
HDFS의 중앙 관리 서버로, 전체 파일 시스템의 메타데이터와 블록 정보를 관리한다. 클라이언트의 요청에 따라 데이터의 위치를 알려주는 중요한 역할을 한다.
1. 메타 데이터 관리
- 메모리에서 관리: NameNode는 파일 시스템의 메타데이터(파일명, 디렉토리 구조, 파일 크기, 권한 정보 등)를 메모리에 저장하고 관리한다. 따라서, 클라이언트의 요청에 빠르게 응답할 수 있다.
- FSimage와 Edit Log: 메타데이터는 FSimage(파일 시스템의 전체 이미지)와 Edit log(최근 변경 사항 기록)로도 저장된다. FSimage는 NameNode가 생성된 이후로부터의 HDFS 네임스페이스를 모두 담고 있으며, Edit log는 FSimage 이후의 모든 변경 사항을 기록한다.
2. 데이터 노드 관리
- 데이터 노드의 목록 관리: NamdNode는 HDFS 클러스터 내의 모든 DataNode를 관리하고, 필요에 따라 리스트를 유지, 변경한다. 이는 관리자가 명령을 내리거나 시스템 모니터링 결과에 따라 이루어진다.
3. 데이터 노드 모니터링
- Heartbeat: DataNode는 3초마다 NameNode에 Heartbeat라는 신호를 보내는데, 이 신호에는 DataNode의 상태와 그 안에 저장된 블록 목록이 포함된다. NameNode는 이 데이터를 통해 DataNode의 상태를 지속적으로 모니터링한다. 일정 기간 동안 Heartbeat가 수신되지 않으면 해당 DataNode를 장애가 발생한 것으로 판단한다.
4. 블록 관리
- 블록 복제 및 관리: NameNode는 각 블록의 위치와 복제본을 관리한다. 장애가 발생한 DataNode의 블록을 다른 DataNode로 복제하거나, 저장 용량이 부족한 경우 블록을 다른 서버로 이동시킨다. 또한, 복제본의 수를 조정하여 데이터를 안전하게 유지한다.
5. 클라이언트 요청 처리
- 클라이언트의 요청 처리: 클라이언트가 HDFS에 데이터를 저장하거나 조회할 때, 항상 NameNode를 통해야 한다. NameNode는 파일의 존재 여부, 권한 등을 확인하고, 데이터를 저장할 위치나 조회할 블록의 위치 정보를 클라이언트에게 제공한다.
DataNode
DataNode는 HDFS에서 실제 데이터를 저장하는 서버들이다. NameNode가 HDFS의 두뇌라면, DataNode는 손과 발처럼 실질적인 데이터를 다루는 역할을 한다.
1. 데이터 저장 (Data Storage)
: DataNode는 클라이언트가 HDFS에 저장하는 실제 데이터를 디스크에 저장한다. 이 데이터는 주로 두 종류로, 하나는 실제 데이터(로우 데이터)이고, 다른 하나는 메타데이터(체크섬, 생성 시간 등)이다.
2. 클라이언트 요청 처리 (Client Request Handling)
: DataNode는 클라이언트로부터 데이터를 읽거나 쓰라는 요청을 받아 처리한다. 클라이언트는 파일의 블록 위치 정보를 NameNode로부터 받고, 해당 DataNode와 직접 통신하여 데이터를 주고받는다.
3. 블록 작업 수행 (Block Operations)
: NameNode의 지시에 따라 DataNode는 자신의 디스크에 있는 블록을 생성, 복제, 삭제 등의 작업을 수행한다.
4. 상태 보고 (State Reporting)
: DataNode는 3초마다 NameNode에 heartbeat 신호를 보내 자신의 상태와 블록 목록을 보고한다. 이를 통해 NameNode는 DataNode의 상태를 모니터링하고, 시스템의 안정성을 유지할 수 있다.
Client
클라이언트는 HDFS에 접근하는 사용자나 애플리케이션을 의미한다. 파일을 읽거나 쓸 때 NameNode에 메타 데이터를 요청하고, DataNode와 직접 데이터를 주고 받는다.
Metadata Operations
클라이언트가 NameNode에 파일이나 디렉토리 정보를 요청할 때 수행되는 작업이다. 클라이언트는 NameNode로부터 파일이 어떤 블록에 저장돼있으며, 그 블록이 어느 DataNode에 있는지 정보를 받는다.
Block Operations
NameNode가 DataNode에게 블록 저장이나 복제 관련 작업을 지시할 때 수행되는 작업이다. 블록을 저장, 삭제, 복제하는 등 실제 데이터와 관련된 작업을 DataNode에서 수행하게 한다.
Racks
DataNode 서버들이 물리적으로 모여 있는 랙(Rack)을 의미한다.
랙은 여러 서버를 모아두는 물리적 장비로, HDFS는 네트워크 트래픽과 장애 시 복구 시간을 최소화하기 위해 데이터 복제본을 다른 랙에 분산해서 저장한다. 예를 들어, 한 랙이 완전히 장애가 나더라도 다른 랙에 복제본이 있어 데이터를 잃지 않는다.
전체적인 아키텍처 Flow
1. 클라이언트(Client)가 파일을 읽거나 쓰려면 먼저 NameNode에 연결하여 해당 파일이 어디에 저장되어 있는지(메타데이터)를 요청한다.
2. NameNode는 DataNode의 블록 정보를 클라이언트에게 제공한다.
3. 클라이언트는 해당 DataNode와 직접 연결하여 데이터를 읽거나 쓴다.
4. 데이터가 DataNode에 쓰여지면, 복제(Replication) 과정이 이루어져 다른 랙(Rack)이나 DataNode에도 데이터 복제본이 저장된다.
Replication
HDFS는 대용량 파일을 신뢰성 있게 여러 서버에 저장하기 위해 블록 단위로 데이터를 나누어 저장하며, 복제본(Replication)을 통해 데이터 손실에 대비한다.
블록 크기(Block Size)
- 파일은 여러 개의 블록으로 나누어 저장되며, 기본적으로 각 블록의 크기는 128MB
- 파일의 모든 블록은 마지막 블록을 제외하고는 동일한 크기
- HDFS는 블록을 채우지 않고도 새 블록을 시작할 수 있는 가변 길이 블록도 지원한다. (ex. append, hsync 사용)
복제 계수(Replication Factor)
- 각 블록은 복제본(Replication)을 여러 서버에 저장해 고장 감내성을 보장한다.
- 복제 계수는 블록의 복사본 수를 나타내며, 파일 생성 시점에 설정되지만 나중에 변경할 수 있다. (기본값은 3개)
NameNode의 역할
- NameNode는 DataNode로부터 주기적으로 heartbeat와 block report를 받아 상태를 모니터링한다.
- Heartbeat: DataNode가 정상적으로 작동하는지 확인하는 신호
- Block report: DataNode에 저장된 모든 블록의 리스트 정보
- NameNode는 이 정보를 바탕으로 블록의 복제본을 관리하고, 복제본의 수가 맞지 않으면 추가 복제 또는 삭제를 수행한다.
HDFS에서 데이터 복제본(Replicat)의 위치 선정은 시스템의 신뢰성과 성능에 중요한 영향을 준다.
복제본을 어디에 저장하느냐에 따라 HDFS의 신뢰성, 성능, 네트워크 사용량이 크게 달라지기 때문이다.
HDFS는 복제본을 어떻게 배치할지에 대한 고유한 규칙과 정책을 가지고 있다.
Rack-aware replica placement
대표적인 복제본 배치 정책 중 하나로, 데이터가 저장되는 서버들이 어느 Rack에 위치해 있는지 인식하고, 한 Rack에 문제가 생겨도 다른 Rack에서 데이터를 복구할 수 있도록 다른 Rack에 복제본을 분산해서 저장하는 방식이다. 서버 장애 뿐만 아니라 Rack 전체가 장애를 겪어도 데이터를 보호할 수 있다.
동일한 Rack 안의 서버끼리는 빠르게 통신할 수 있다. 하지만 서로 다른 Rack에 있는 서버끼리 통신할 때는, 각 Rack에 있는 스위치(Swtich)를 통해 통신해야 하므로 네트워크 대역폭이 더 많이 필요하고 속도가 느려질 수 있다.
Hadoop의 Rack Awareness
Hadoop의 Rack Awareness는 네임노드(NameNode)가 각 DataNode가 어느 Rack에 위치해 있는지 인식하는 능력.
즉, 네임노드가 각 서버(DataNode)의 Rack ID를 알고, 이 정보를 사용해 데이터 복제본을 저장하거나 복구할 때 최적의 결정을 내릴 수 있다.
1. 간단한 복제 정책
: Hadoop에서는 복제본을 저장할 때 서로 다른 Rack에 분산해서 저장하는 것이 일반적이다. 예를 들어, 하나의 복제본은 Rack 1에, 또 다른 복제본은 Rack 2에 저장한다. 이를 통해 Rack 전체가 장애가 발생했을 때도 다른 Rack에 저장된 복제본을 이용해 데이터를 복구할 수 있다.
2. 부하 분산(Load Balancing)
: 복제본을 여러 Rack에 분산해 저장하면, 클러스터 전체의 부하가 고르게 분산된다. 네트워크 트래픽과 서버의 처리 부담을 줄여 시스템 성능을 향상시킨다.
3. 쓰기 비용 증가
: 문제는 이러한 복제 정책은 데이터를 여러 Rack에 걸쳐서 복제해야 하므로 데이터를 저장(쓰기)할 때 더 많은 네트워크 비용이 발생할 수 있다. 즉, 데이터를 여러 Rack에 전송해야 하기 때문에 쓰기 작업이 더 느려질 수 있다.
Block Placement Policy (Default)
HDFS의 기본 복제본 배치 정책(Block Placement Policy Default)은 복제 계수(replication factor)가 3인 경우를 기준으로 한다.
1. 첫 번째 복제본: 가능한 한 Writer와 같은 Rack에 있는 DataNode에 저장된다.
- 만약 Writer가 특정 DataNode에서 동작하는 경우, 첫 번째 복제본은 로컬에 저장된다.
- Writer가 DataNode가 아닌 다른 노드에서 동작하는 경우, 같은 Rack 내 임의의 DataNode에 저장된다.
2. 나머지 두 개의 복제본: Writer와 다른 Rack의 서로 다른 두 개의 DataNode에 각각 저장된다.
- 즉, 총 unique rack 의 수는 2개이다.
복제 계수가 3보다 클 때, 4번째 복제본은 복제본이 고르게 분산되도록 하기 위해 무작위로 다른 랙에 배치된다.
장점
1. 쓰기 성능 향상: Rack 간 트래픽을 줄여 쓰기 성능 개선
2. 데이터 신뢰성 유지: Rack 장애보다 노드 장애가 더 자주 발생하므로, 신뢰성과 가용성에 큰 영향을 미치지 않는다.
단점
1. 네트워크 대역폭 절감 부족: 모든 복제본이 동일한 Rack에 있지 않기 때문에, 네트워크 대역폭을 완전히 최적화하지는 못한다.
2. 복제본 분산 불균형: 복제본이 1:2 비율로 위치하므로, 모든 Rack에 균등하게 분산되지 않는다.
Replica Selection (Read)
HDFS는 읽기 요청 시 네트워크 대역폭 사용을 줄이고 지연 시간을 줄이기 위해, Reader와 가까운 복제본에 데이터를 읽도록 최적화한다.
- Reader와 같은 Rack에 복제본이 있다면, 해당 복제본에서 데이터를 읽는다.
- 클러스터가 여러 데이터 센터에 걸쳐 있을 경우, 같은 데이터 센터에 있는 복제본을 우선 선택한다.
Safemode
NameNode가 초기화될 때, 시스템은 Safemode라는 특별 상태에 진입한다.
이 동안 복제 작업은 일어나지 않으며, DataNode로부터 받은 Block Report를 기반으로 복제가 적절히 이루어졌는지 확인한다.
모든 블록의 복제가 일정 수준 이상 완료되면 Safemode를 종료하고, 복제가 부족한 블록은 그 때 복제 작업이 진행된다.
'Data Engineering > Hadoop' 카테고리의 다른 글
Hadoop을 사용하는 이유 (0) | 2024.09.03 |
---|