Hadoop이 지금에서야 Spark, Hive와 같이 다양한 오픈소스 프로젝트가 결합되서 쓰이지만, 초창기의 시스템 뼈대는 HDFS와 MapReduce로부터 시작되었습니다. 얼마 안가 Hadoop이 v2.0으로 버전업 되면서 MapReduce의 역할 일부가 YARN이라는 구성 요소로 떨어져 나와, 마침내 HDFS, MapReduce, YARN의 3진 체계가 이루어졌습니다.
3가지 각각의 요소의 기능은 다음과 같습니다.
- HDFS: 거대한 데이터를 여러 컴퓨팅 노드에 나눠 저장하는 분산 스토리지 시스템
- MapReduce: 다량의 데이터를 집계하기 위한 분산 데이터 처리 엔진
- YARN: Hadoop 클러스터 전체에서 수행되는 작업과 필요한 리소스를 관리하는 모듈
1. HDFS
빅 데이터라고 하면 "데이터가 개수가 많다"로 해석할 수도 있지만, 이는 반만 맞은 표현입니다. 데이터 양만 많은게 아니라, 말 그대로 사이즈가 매우 큰(big) 데이터 파일도 빅데이터에 포함됩니다. 영상 이미지나 대규모 웹서버 로그가 이에 해당됩니다.
HDFS는 그냥 용량만 많은 파일시스템이 아니라, 앞서 이야기한 큰 사이즈의 데이터를 저장하는 데 특화된 시스템입니다.
HDFS의 정확한 명칭은 "Hadoop Distributed File System"이고, 분산(Distributed) 시스템답게 거대한 파일 하나를 여러 데이터 블록으로 쪼개어 저장하는 것이 특징입니다. 쪼개진 블록당 크기는 기본적으로(default) 128MB
입니다.
이렇게 잘려진 데이터 블록을 다 합쳐놓으면 어떤 경우에는 하드디스크 1개의 용량보다 거대랑 수 있습니다. 그래서 HDFS는 데이터 블록들을 클러스터 내에 여러 컴퓨터에 조금씩 분배하여 저장하도록 합니다.
또한, 각각의 데이터 블록을 여러 번 복사하여 다른 컴퓨터가 나눠가지는데요. 이는, 데이터 블록 일부가 유실되었을 때를 대비하여 미리 백업본을 다른 저장공간에 대비시켜두는 전략이라 할 수 있습니다.
1-1. HDFS의 특징
위 설계 원리에 따라, HDFS는 다음과 같은 특징을 지니고 있습니다.
- 블록 단위 저장: HDFS는 데이터를 통으로 스토리지에 집어 넣지 않고, 원본보다 작은 블록 단위로 나누어서 저장합니다. 원본 파일 크기가 기본 블록 사이즈보다 작으면 기존 파일 그대로 저장하고, 블록 사이즈보다 큰 파일은 블록 단위 나누어 저장하기 때문에 단일 디스크가 수용할 수 있는 공간보다 더 큰 파일도 저장할 수 있습니다.
- 데이터 안정성: HDFS는 스토리지 장애/데이터 유실 문제에 대처하기 위해서 각 블록을 복제하여 저장합니다. 복제된 블록은 서로 다른 컴퓨팅 노드에 저장되므로, 한 블록에 문제가 생기더라도 복제된 다른 블록을 이용해서 데이터를 복구 가능 합니다.
- 데이터 무결성: HDFS는 데이터 읽기/쓰기 작업에 최적화된 아키텍쳐로, 파일의 수정은 지원하지 않습니다. 다만 이로 인해 데이터 무결성이 보장되며, 효율적인 병렬 처리가 가능합니다. 파일 수정 외에, 파일 이동, 삭제, 복사는 가능합니다.
- 배치 작업에 적합한 설계: HDFS는 데이터 처리량(Throughput)을 향상 시키기 위해 스트리밍 방식으로 데이터에 접근합니다.
1-2. HDFS 아키텍쳐
작업 노드(Node)의 구분
- Name Node: 각 데이터 블록이 놓여진 장소를 기록하는 테이블을 관리합니다. 데이터 블록의 생성, 수정, 이동 되었는지 등을 모니터링합니다.
- Data Node: 데이터 블록들이 실제로 저장되는 공간입니다.
HDFS에서의 읽기(Reading)
어떤 클라이언트가 데이터를 조회하고 읽는(Reading) 작업을 수행하려 한다고 쳐봅시다. 데이터 블록은 곳곳에 쪼개져 있기 때문에 클라이언트가 곧바로 파일시스템에서 데이터를 불러 올 수는 없습니다.
대신, Name Node에게 "A라는 데이터를 찾고 싶어"라고 이야기하면, Name Node는 데이터 A의 부분들이 가령 a, b, c라면, 이들의 저장되어 있는 Data Node 목록을 클라이언트에게 제공합니다.
HDFS에서의 쓰기(Writing)
이번에는 클라이언트가 HDFS에 새로운 파일을 저장하려는 상황입니다.
클라이언트는 Name Node에게 파일을 저장하기 위한 새로운 entry를 마련할 수 있는지 물어봅니다. Name Node가 OK라고 답한다면, 클라이언트는 임의의 Data Node에 파일 저장 요청을 보냅니다.
요청을 받은 Data Node는 다른 Data Node들과 통신하면서 데이터 블록을 어떻게 쪼갤지, 사본(replica)는 각각 어느 Node에게 맡길지를 결정합니다.
Data Node 간의 합의가 끝나면, 제일 처음에 요청을 받았던 Node가 파일이 성공적으로 저장되었고, 각 데이터 블록이 저장되어 있는 위치를 클라이언트와 Name Node에게 통보합니다.
2. MapReduce
MapReduce는 데이터를 분산 처리하는 엔진입니다. HDFS가 각 클러스터 노드에 데이터 저장 공간을 예약하는 역할을 수행하면, MapReduce는 데이터 처리 작업을 클러스터 노드마다 적절히 분배해주는 일을 합니다.
여기서 말하는 “데이터 처리”는 일반적인 데이터베이스 시스템과 마찬가지로, 특정 조건에 부합하는 결과물들만 찾아서(Filtering), 분석하고자 하는 결과를 도출(Aggregation)하는 것입니다.
이 Filtering과 Aggregation 작업을 Hadoop에서는 Map과 Reduce라는 용어로 표현했다고 봐도 무방합니다. 대신, 분산 컴퓨팅의 원리가 들어간 게 핵심이죠.
2.1 MapReduce의 과정
MapReduce은 일반적으로 전체 작업을 Map와 Reduce로 구분지으나, 실제 동작 과정을 Map → Shuffle → Reduce 단계로 나누어 설명하는 것도 가능합니다.
- Map: raw data를 key/value 쌍으로 묶음
- Shuffle(Sort): key/value 쌍을 정렬
- Reduce: Mapping과 Sorting을 거친 key/value 쌍에서 유의미한 정보를 획득
Map단계에서 다루는 Input 데이터는 서로 다른 HDFS block에서 불러온 것들입니다. 한 MapReduce 작업에서 로드하는 block의 수가 많아진다면, 당연히 그 양만큼 이후 단계에서의 연산량이 늘어나겠죠.
그렇기 때문에, Hadoop에서는 Map과 Reduce 작업도 여러 subtask로 쪼개어 각기 다른 컴퓨터에 할당하는 방법을 채택합니다. 그리고 이러한 작업 스케쥴링은 후술할 YARN이라는 리소스 관리자가 담당하게 되죠.
예시로 보는 MapReduce
원본 데이터가 아래와 같은 테이블이라고 해봅시다.
위 데이터에서 “각 지역(Location)별 점수(Score) 평균”을 알아내려 합니다. 연산에 필요한 부분은 우측의 2개의 데이터 열이 되겠죠.
Map 과정에서 각 데이터가 key:value 쌍으로 묶입니다. 본 예시에서는 지역(Location):점수(Score) 형태로 표현이 되겠네요. 동일한 Key를 가진 요소가 여럿이 존재하는 것은 문제되지 않습니다.
Shuffle 단계에서 같은 Key를 가진 요소들끼리 그룹지어줄테니 말이죠.
마지막으로 Reduce 단계에서 원하는 평균값을 도출해낼 수 있습니다.
3. YARN
YARN은 리소스 관리자입니다. 더 자세하게는, Hadoop 클러스터에서 실행되는 작업들을 스케쥴링/모니터링하고, 작업을 수행하기 위한 리소스(CPU, 메모리, 디스크, 네트워크)를 분배하는 역할을 맡습니다.
HDFS 내에서 데이터를 기왕이면 빠르게 읽을 수 있도록, locality를 고려해서 데이터 블록의 저장 위치를 결정하는 것 역시 YARN의 기능 중 하나이죠.
무엇보다, Hadoop 시스템은 여러 클라이언트로부터 동시에 데이터 읽기/쓰기, 그리고 MapReduce 엔진이 처리해야하는 작업들을 요구 받을 수 있습니다. YARN은 동시간대에 들어온 작업 요청들을 절절한 스케쥴링 방식에 기반하여 컴퓨팅 노드에 배분하고 작업 수행 여부를 실시간으로 검토합니다.
3.1 YARN의 구조
YARN의 중추에는 Resource Manger가 존재하고, 여기에 하나 이상의 Node Manager가 연결됩니다.
- Resource Manager: 클러스터 전체의 자원을 모니터링하고 관리합니다. Resource Manager는
Scheduler
와Application Manager
라는 2 가지 요소로 구성됩니다.- Scheduler: 내부 스케쥴링 조건에 의거하여 실행중인 애플리케이션에 자원을 할당합니다.
- Applications Master: Client의 작업 요청을 검토하고 애플리케이션을 실행하기 위해 필요한 리소스를 Resource Manager와 협상합니다.
- Node Manager: 내부에 배치된 Container의 자원 사용량(CPU, 메모리, 디스크, 네트워크)을 모니터링하고 Resource Manager에 보고합니다.
- Container:
Applications Master
에 의해 합의된 만큼의 리소스를 받아 Task를 수행합니다.
- Container:
3.2 YARN의 작업 스케쥴링 방식
클라이언트의 작업 요청 중에는 우선순위(priority)가 높은 것도 있을테고, 때론 나중으로 미뤄두어도 되는 것들 역시 존재할 겁니다. 사용자가 작업의 우선순위를 직접 정해주지 못한다면, 시스템에서 작업 스케쥴링 정책에 따라 가진 자원을 배분해야합니다.
아래는 YARN에 탑재된 대표적인 스케쥴링 방식입니다.
- Capacity Scheduler: 각 작업마다 최대 사용가능한 자원량(maximum capacity)가 내부 기준에 의해 결정되어 있습니다. Hadoop에서 채택한 기본(default) 스케쥴러입니다.
- Fair Scheduler: 클라이언트들의 작업 요청마다 균등하게 1/n 만큼 자원을 할당합니다.
- FIFO (First-In-First-Out) Scheduler: 먼저 들어온 작업 요청은 무조건 먼저 처리하는 원칙입니다. 이전 작업이 완수될 때까지 다음 작업은 대기 상태에 있어야 하므로 자원 활용의 효율성이 떨어집니다.