Deep Dive 포스팅은 공부를 통해 알게된 지식을 기록, 공유하기 위한 글입니다.
잘못된 정보에 대한 지적과 조언 감사합니다.
Hadoop 구축, 운영을 다수 진행하면서 각 노드들에 대한 깊은 지식과 동작 원리, 버전별 차이를 알고 싶어 탐구하게되었고, 버전별로 추가된 노드도 있고 내부 동작이 변경되는 경우도 있었습니다. 이에 개인적으로 새로운 버전의 흐름에 따라 정리하는 것이 이해에 도움이 된다 생각하여 달라진 버전의 흐름에 따라 다소 길게 정리하였습니다.
Hadoop이란?
Hadoop은 여러 대의 서버로 이루어진 클러스터 환경에서 대용량의 데이터를 분산 저장 및 처리하는 Java기반의 오픈 소스 프레임워크입니다.
하둡의 특징!
1. Hadoop은 들어오는 데이터의 형식(csv, json, img)에 구애 받지 않고 파일 그대로 저장합니다. (유사 Object Storage)
2. Hadoop은 들어오는 파일(데이터)을 Block 단위로 나누어 저장합니다. 이 때, 나누어지는 Block Size는 버전 별로 상이하지만, 128MB를 권장하며, 꽤 큰 Size이지만, 탐색하려는 Block의 Size가 작게되면, 그만큼 더 많은 여로 노드에 분산된 여러 개의 Block을 찾아야하기 때문에, 네트워크 트래픽이 증가하게됩니다.
들어오는 파일의 크기가 지정된 Block Size보다 작거나, Block으로 나눈 후 마지막 Block의 Size가 지정된 Block Size보다 작을 시, 지정된 Size만큼 용량이 할당 되는 것이 아닌, 실제 파일 혹은 남은 Block Szie 용량만큼만 차지합니다.
ex) 192MB의 파일, 지정 Block Size 128MB일 때, 128MB 1, 64MB 1, 2개의 Block으로 나누어집니다.
3. Hadoop은 Block을 3복제하여 저장합니다. 이는 Block의 손실을 대비하기 위함이고, 이에 저장 공간은 3배가 필요합니다. 복제 개수는 사용자가 정의할 수 있고, Default 값은 3입니다.
4. Hadoop은 HDFS라는 파일 시스템을 활용하는데 이는 읽기 중심의 컨셉을 가지고 있습니다. 이에, 파일의 수정은 지원하지 않습니다. (Append, Delete)
5. Hadoop은 데이터의 지역성을 활용하여, 데이터를 처리 시, 해당 데이터를 이동하지 않고, 해당 데이터가 저장된 노드에서 처리 후, 취합하기에 비용이 절감됩니다.
하둡의 등장 (v1)
Hadoop v1에서는 분산 저장, 병렬 처리 프레임워크가 정의 되었습니다.
주요 핵심 코어로 HDFS(분산 저장), MapReduce(병렬 처리)가 있습니다.
HDFS(Hadoop Distributed File System):
Hadoop은 HDFS라는 파일시스템을 통해 데이터를 분산 저장합니다. HDFS는 들어오는 파일을 Block 단위로 나누어 클러스터화 된 여러 노드에 분산하여 저장합니다.
또한, Block의 손실을 대비하여 나누어진 Block을 복제하여 저장합니다. 기본 복제 수는 3개이며, 이에 저장 공간이 3배 필요하게됩니다.
HDFS의 컨셉은 읽기이며, 파일의 수정은 불가합니다.
MapReduce:
맵 리듀스는 분산, 병렬 환경의 대용량의 데이터를 처리하기 위해 설계된 프로그래밍 모델입니다.
데이터가 들어오면, 특정 크기의 Block로 나눈 후, 각각의 Block에 대해 Map Task, Reduce Task를 수행합니다.
Map과 Reduce는 입/출력으로 Key/Value 구조를 사용합니다. Map은 데이터를 Key, Value 형태로 묶고, 해당 형태의 데이터를 List 형식으로 반환합니다. 후 Reduce는 Map에서 처리한 데이터 중 중복된 Key 값을 가지는 데이터를 제거 및 합쳐 원하는 데이터의 형태로 추출하는 작업을 수행합니다.
하둡의 구조와 동작 (HDFS 관점)
Hadoop v1은 크게 NameNode와 Secondary NameNode, DataNode로 구성됩니다.
Namenode는 Metadata와 DataNode를 관리하는 역할을 수행합니다. Metadata에는 HDFS 내 존재하는 파일의 이름, 크기,
생성 시간, 권한 유저, 그룹 소유자, Block의 정보 등이 담겨있는 데이터입니다. Metadata 관리는 fsimage, edits log, block report로 이루어집니다.
fsimage: 파일에 매핑된 Block의 정보 등을 포함, 전체 namespace 정보
editLog: HDFS 파일 생성, 삭제 등의 Transaction 로그
Block Reports: DataNode로 부터 주기적으로 보고 받으며, DataNode 내 저장된 Block 목록과 Block이 실제 저장된 로컬 디스크의 위치
fsimage와 editLog 파일은 v1기준, 하둡 설치 시 정의된 로컬 디스크 내 namenode 디렉토리 하위 current 디렉토리에 생성됩니다. 하둡 운영 중 발생하는 수정 사항(HDFS 파일 생성 혹은 삭제)은 곧바로 fsimage에 반영되지 않고, 또한 새로운 fsimage를 만들지 않습니다. 이러한 변경 사항(Transaction Log)은 editLog 파일에 기록되는 데 주기적으로 이 editLog 파일이 fsimage에 반영되어 새로운 fsimage를 만들고 이를 check point라고 합니다.(사용자가 주기 설정 가능)
NameNode가 기동되거나 위 check point 상황이 발생하면, fsimage와 editLog가 병합된 새로운 fsimage와 DataNode로 부터 주기적으로 보고 받는 Block Reports를 메모리 상에서 관리하여 최신 상태의 HDFS 정보를 유지하게 됩니다.
NameNode 구동 시, 지속해서 editLog 파일이 생성되고, 트랜잭션이 빈번하게 일어나게 되면, editLog 파일이 빠르고 많이 생성되어, NameNode의 디스크 용량 부족 문제와 재구동 되는 시간이 느려지는 현상이 발생될 수 있습니다.
이러한 NameNode의 Metadata 관리에 대한 부하를 줄이기 위해 Seconary NameNode가 존재합니다.
Secondary NameNode는 위 NameNode의 메타 데이터 관리 부하를 덜어주기 위해 editLog와 fsimage를 NameNode로 부터 복사, 주기적으로 병합하는 역할을 분담합니다. 병합된 새로운 fsimage를 NameNode에게 전달하고 NameNode는 받은 새로운 fsimage를 통해 Metadata를 관리합니다. 또한, 병합이 완료된 editLog 파일은 정리되어 디스크 용량 확보에도 도움이 됩니다.
(* Secondary NameNode는 백업용이 아닌, NameNode의 일을 덜어주기 위한 보조용의 노드)
DataNode는 파일이 나누어진 Block을 실제로 저장하는 역할을 수행합니다. 또한 NameNode에게 주기적으로 HeartBeat와 Block Reports를 전송하여 자신의 상태, Block의 위치 정보 등을 전송합니다.
하둡의 구조와 동작 (MapReduce 관점)
v1 기준, MapReduce 프로그램은 Job이라는 하나의 작업 단위로 관리되었습니다.
client로 부터 MapReduce 작업이 요청되면, Job Tracker와 Task Tracker가 클러스터 내 할당됩니다.
JobTracker는 클러스터의 전반적인 리소스를 관리하고, Job을 처리하기 위해 실행될 Map과 Reduce의 개수를 계산 및 결정하고 알맞는 Task Tracker에게 Job을 할당합니다. 또한, Job의 실행 이력도 관리합니다. 보통 NameNode에서 실행하지만, 꼭 그러지 않아도 무관합니다.
TaskTracker는 Job 수행을 요청 받아 MapReduce Task를 실행합니다. DataNode에서 실행됩니다..
Job Tracker와 Task Tracker는 HeartBeat를 통해 네트워크 통신으로 각 상태, Job 실행 정보 등을 공유합니다. Task Tracker에 문제가 생기면 다른 대기상태의 Task Tracker를 Job Tracker가 찾아 Task를 할당합니다.
이에 Job Tracker는 리소스 관리, Job 이력 관리, Task Tracker와의 통신으로 수행할 작업이 많아져 병목현상이 발생했습니다.
하둡 v1 문제점
- NameNode가 고장이나면, 클러스터에 대한 요청을 받을 수 없고, 메타데이터 접근도 불가하여 HDFS 파일 내용을 확인 할 수 없습니다. 즉, NameNode의 단일장애지점(Single Point Of Failure, SPOF)이 문제가 되었습니다.
- MapReduce 작업 환경에서 Job Tracker가 클러스터 전체 리소스 관리, Job 이력 관리, 알맞은 Task Tracker를 찾아 Job 할당 등 여러 역할을 수행하기에 병목현상이 발생할 수 있습니다.
고가용성과 Yarn 아키텍처의 도입, 하둡 v2
v1에서의 Hadoop은 NameNode가 고장이 나면, 클러스터 요청, editLog 등의 메타데이터 접근 불가로 클러스터의 제 기능을 할 수 없습니다. 즉, NameNode는 단일장애지점(Single Point Of Failure, SPOF)이었습니다.
이를 해결하기 위해 고가용성(HA, High Availability) 아키텍처가 도입됩니다. 이에 추가된 노드들이 있습니다.
Journal Node:
v1에서의 Hadoop은 editLog를 NameNode 자신의 로컬디스크에 저장하였지만, v2부터는 NameNode가 Journal Node에게 editLog의 저장을 요청합니다. editLog는 Journal Node의 로컬 디스크에 저장되며, 공유되는 editLog의 저장소는 Journal Node가 아닌 NFS로도 구현 가능합니다. Journal Node는 다수의 노드, 홀수 개의 노드에서 동작합니다.(최소 3대)
Journal Node 역시 SPOF 대상이 될 수 있고, 이는 editLog의 손실로 이어질 수 있기 때문에, 다수의 노드에 복제하여 저장하기위함과, 또한 NameNode가 Journal Node의 오류의 영향을 받지 않기 위해 과반 수 이상의 Journal Node가 동작하여야 하기 때문에 홀 수개의 노드로 구성됩니다.(짝수면 정상/비정상의 비율이 동률일 가능성이 있기 때문)
editLog에 대한 쓰기 요청은 Active NameNode만이 권한을 가지고 있고, Standby NameNode는 주기적으로 JournalNode 내 editLog 파일을 읽습니다. 또한 JournalNode 중 하나의 노드가 손상되어도 정상적으로 동작하는 데, 이 기능은 Zookeeper가 아닌 자체적으로 개발된 기능입니다.
Active NameNode:
실질적인 NameNode 역할을 수행하는 활성 상태의 NameNode입니다. 위에서 언급드렸듯, editLog의 저장을 Journal Node에게 요청합니다.
Standby NameNode:
Active NameNode의 다운을 대비한 대기 상태의 NameNode이며, Active NameNode가 기동 중지되면, 해당 NameNode가 Active NameNode가 되어 본래 NameNode의 역할을 수행합니다. 또한, 대기 상태일 때, 주기적으로 Journal Node 내 editLog를 읽어 fsimage를 갱신 합니다. (v1의 Secondary NameNode를 고가용성 도입 후 사용하지 않는 까닭인 것 같습니다.)
또한, Standby NameNode 역시 DataNode로 부터 HeartBeat와 Block Reports를 받게 되고, 이에 Active NameNode와 동일한 메타 데이터를 유지, Active와 Standby가 바뀌는 fail over 상황에서 빠른 전환을 할 수 있게 됩니다.
Zookeeper:
분산 코디네이터 툴로써, Hadoop 이외의 프레임워크에서도 많이 사용됩니다. 하둡 고가용성에서의 Zookeeper는 두 개의 NameNode에 대한 세션을 ZKFC를 통해 유지 하며, 세션이 끊겼을 때, 해당 NameNode에 문제가 발생함을 인식합니다. 또한, 리더 선출 기능을 통해 어떤 Node가 Active로 선정될지 결정하는 역할을 합니다.
ZKFC( Zookeeper Failover Controller):
ZKFC는 NameNode와 Zookeeper 중간 역할을 담당하여, Active/Standby NameNode가 설치된 2개의 노드에 각각 실행됩니다. 자신이 설치된 노드에서 기동되고있는 NameNode의 상태를 HeartBeat를 통해 모니터링 하며, Active NameNode가 중지 될 시, ZKFC와 Zookeeper 마스터의 세션을 끊고, StandBy NameNode를 Active로 승격시키며, 기존의 Active NameNode를 제거합니다. ZKFC를 통해 Active NameNode는 항상 한 노드임을 보장 받습니다.
DataNode:
v1과 같이 Block이 실제 디스크에 저장되는 노드이며, 달라진 점은, v2에서부터 Active, Standby NameNode 두 노드 모두에게 Block Reports와 HeartBeat를 전송합니다.
위 노드들의 추가로 NameNode의 SPOF가 해결되어 클러스터 운영 및 메타데이터 관리의 가용성이 높아졌습니다.
두 번째로, Yarn 아키텍처의 도입입니다. v1의 또 다른 문제점은 MapReduce 환경에서 Job Tracker의 많은 역할로 인한 병목 현상이었는데요. v2부터 도입된 Job Tracker의 역할을 분담하기 위한 Yarn의 구성요소를 알아보겠습니다.
2버전부터 작업의 단위는 job에서 Application으로 명칭이 변경됩니다.
Resource Manager:
클러스터 전체의 리소스 관리 및 할당을 담당하며, NameNode와 같이 Active/Standby 개념이 존재합니다.
크게 Scheduler와 Application Manager로 이루어집니다.
Scheduler: 용량, Queue등 제약 조건에 따라 여러 실행 중인 Application들에 자원(Container)을 할당하는 작업을 수행 합니다.
Application Manager: 클라이언트가 제출한 Application을 승인, Application Master를 실행하기 위한 Container를 확 인하고, Application Master의 상태를 작업이 종료될 때 까지 관리합니다.
Node Manager:
클러스터의 각 노드에서 실행되며, 설치된 노드의 리소스를 모니터링하고, Resource Manger에게 보고합니다.
또한, 추후 해당 노드에 작업이 수행되는 Container가 할당되는데, 이 Container의 리소스 사용량 감시, Resource Manager에게 보고합니다.
Application Master:
Application은 제출된 단일 작업을 의미하며, 각 작업들은 고유한 Application Master를 가지게 됩니다. Application Master는 해당 Application의 실행을 조정, 오류를 관리하는 역할을 합니다. Node Manager와 함께 동작하여 Task를 실행, 모니터링하고 Resource Manager로부터 자원(Container)을 요청, 할당 받고, 주기적으로 Resource Manager에게 Heart Beat를 전송합니다.
Container:
개별 노드에 할당받은 자원입니다. RAM, CPU, Memory 등이 있습니다. Container 안에서 실질적인 Task가 수행됩니다.
동작 방식:
1. 클라이언트가 Resource Manager에게 Application을 요청합니다.
2. Resource Manager가 Application Master를 기동하기 위한 Container를 협상 후 기동합니다.
3. Application Master가 기동되면 Application 수행을 위한 자원(Container)를 Resource Manager에게 요청합니다.
4. Application Master가 할당 받은 Container를 Node Manager에 할당하고, 이 안에서 실제 Task를 수행합니다.
5. 모든 작업이 완료되면 Application Master가 Resource Manager에서부터 등록이 해제, 종료됩니다.
하둡 v2 정리:
v1의 문제점이었던 HDFS 관점의 Name Node의 단일 장애 지점을 Active/StandBy Name Node의 도입으로 해결되었습니다. Zookeeper, zkfc를 통해 Active/StandBy Name Node의 선정, fail over가 가능해졌으며, Journal Node를 통해 EditLog의 저장, 복제를 통해 메타 데이터 유실을 방지하며, 1버전의 Name Node가 수행했던 메타데이터 체크포인팅 작업을 StandBy Name Node가 수행하여 Name Node의 부하를 줄였습니다. 또한 1버전의 Name Node가 EditLog를 저장하였는데, 이는 디스크 용량의 문제, 해당 노드가 에러 시, 메타데이터의 유실이 발생할 가능성이 존재하였지만, 이 역시 Journal Node의 도입으로 Edit Log 저장을 Journal Node가 대신하고, 3대 이상의 홀수로 동작하여 복제 저장을 통해 메타데이터 유실을 방지 할 수 있습니다.
MapReduce관점의 Job Tracker의 너무 많은 역할로 인한 병목현상을 해결하기 위해, 작업의 요청에 대한 응답, 리소스 관리, 스케쥴링 기능을 Yarn 아키텍처를 도입하며 인수하였습니다. 또한, Yarn은 MapReduce 작업과 더불어, Spark, Hive 등의 여러 프레임워크의 작업들도 사용될 수 있습니다.
성능 개선을 위한 하둡 v3
HDFS는 Fault tolerance의 보장, Read 성능을 위해 기본적으로 들어오는 파일을 3복제하여 분산 저장합니다. 이는 1GB의 파일을 저장한다면, 클러스터 상에는 3GB가 저장되는 것이므로 저장 용량을 3배 차지한다는 점이 있습니다. 이러한 저장 용량의 효율성을 위해 Erasure Coding이 등장하였습니다.
Erasure Coding:
이레이져 코딩은 패리티 블록을 활용하여 1GB의 저장을 3GB가 아닌 1.5GB 만큼 디스크를 사용하게됩니다.
(3배 -> 1.4배)
이레이져 코딩은 디스크 RAID 구성에서 주로 사용하는 알고리즘을 활용합니다. hdfs 명령어를 통해 적용 가능합니다.
또한, v1부터 사용되었던 쉘 스크립트의 수정, 디버깅이 진행되었고, 스크립트가 이해하기 쉽도록 수정되었으며, java 8버전을 지원하게 되었습니다. Native Code 또한 최적화 되었으며, 고가용성을 위한 Active/Standby NameNode 중 StandBy NameNode가 한 노드만 추가할 수 있었지만, 여러 노드를 추가할 수 있도록 개선되었습니다.
또한 Object 저장소로 Ozone이 추가되었으며, 기존 사용되던 NameNode, DataNode 등 디폴트 포트들이 대거 변경 되었습니다.
잘못된 정보가 있을 시, 지적과 조언 감사합니다.
긴 글 읽어주셔서 감사합니다.
'BigData > Hadoop' 카테고리의 다른 글
java.lang.RuntimeException: Unable to fence NameNode 에러 현상 해결 (0) | 2024.08.16 |
---|---|
yarn vcore 초과 할당 시 설정 (0) | 2024.06.20 |
yarn) spark yarn job container 로그 설정 (0) | 2024.02.13 |
yarn-site.xml 튜닝 (0) | 2023.09.07 |
yarn capacitiy 스케줄러 설정 (0) | 2023.07.26 |