Hadoop 이란 HDFS + MapReduce로 구성되어 있습니다. (이전 글 : https://ahea.wordpress.com/2017/03/29/hadoop-eco-system-정리-1-20170329/ ) 각 시스템의 아키텍처에 대해 정리해 보았습니다.
1. HDFS
- Hadoop Distributed File System
- 블록 구조의 파일 시스템 (특정 크기의 블록으로 나누어 분산된 서버에 저장)
- 분산 파일 시스템 : 블록을 다중 노드에 분산해서 보관
- Replication : 하나의 블록은 여러 노드에 복제, 특정 노드 장애에 무정지 대응
네임노드 (Name Node)
- 메타데이터 관리 : 파일 스스템을 유지하기 위한 메타데이터 관리
- 데이터 노드 모니터링 : 데이터 노드는 네임 노드에게 3초 마다 하트비트(heartbeat)를 전송
- 네임 노드는 이를 이용해 데이터 노드의 실행 상태와 용량을 체크
- heartbeat를 전송하지 않은 데이터 노드는 장애 서버로 판단
- 블록 관리 : 장애가 발생한 데이터 노드의 블록을 새로운 데이터 노드에 복제
- 용량이 부족하다면 여유가 있는 데이터 노드에 블록을 옮긴다.
- 클라이언트 요청 접수 : 클라이언트가 HDFS에 접근하려면 반드시 네임노드의 먼저 접속
- HDFS에 파일을 저장할 경우 기존 파일의 저장여부와 권한 확인 절파를 거쳐 저장을 승인
- 이중화가 가능해졌지만, 중요한 정보들을 가지고 있으므로, 물리적으로 Disk 백업 체계를 고려해야한다.
- SPOF ( Single Point Of Failure )
보조 네임노드 (Secondary Name Node)
- 네임노드가 메타데이터를 메모리에 담고 처리하는데 만약 서버가 리부팅되는 경우 사라질 수 있다.
- HDFS는 이러한 문제로 인해 editslog와 fsimage라는 두 개의 파일을 생성
- editslog : HDFS의 모든 변경이력을 저장
- fsimage : 메모리에 저장된 메타데이터의 파일 시스템 이미지를 저장하는 파일
- editslog가 커지면 fsimage를 만드는데 시간이 많이 소요되는 단점
- 세컨드리 네임노드가 fsimage를 갱신 (체크포인트) : 세컨드리 네임노드 = 체크포인팅 서버
- 네임노드의 백업이 아닌 fsimage를 줄여주는 역할
- fsimage가 너무 커서 네임노드가 메모이레 로딩되지 못하는 경우를 예방하기 위해 사용되는 것
데이터 노드 (Data Node)
- 클라이언트가 HDFS에 저장하는 파일을 로컬 디스크에 유지
- 파일을 두가지로 저장되는데 하나는 실제 저장되는 로우 데이터이며, 다른 하나는 체크섬이나 파일 생성 일장 같은 메타데이터가 저장된 파일
- Hadoop이 자체적인 Replication을 해서 High Availability를 보장하기 때문에 물리적인 Disk 백업이 필요하지 않다.
구글 이미지 검색 중 HDFS architecture로 검색하니 다음 이미지가 나왔다. 이 그림은 HDFS 아키텍쳐의 설명을 자세하게 설명되어 있습니다. 이 중 파일 저장과 파일 읽기에 관한 내용을 간단하게 정리해봤습니다.
파일 저장
- 클라이언트에서 먼저 네임노드와 통신 과정을 통해 스트림(DFSOutputStream)을 생성
- 생성된 스트림을 통해 클라이언트에서 파일을 각 데이터 노드에 전송. 저장할 파일을 패킷 단위로 나누어 전송
- 파일 전송이 완료되면 클라이언트에서는 네임노드에서 얻은 스트림을 close하면 남은 모든 패킷이 flush.
- 클라이언트에서 네임노드의 complete 메소드를 호풀해서 정상적으로 저장되었다면 true가 반환.
파일 읽기
- 클라이언트에서 네임노드이 입력스트림 객체(DFSInputStream)를 통해 스트림 객체를 생성
- 생성된 스트림 객체를 이용하여 기본 블록의 10배수 만큼 조회
- 클라이언트에서 스트림 객체에서 블록리더기를 생성하는데 블록이 저장된 데이터노드가 같은 서버에 있다면 로컬블록리더기(BlockReaderLocal)을 생성, 원격에 있다면 원격블록리더기(RemoteBlockReader)를 생성한다.
- DFSInputStream은 파일 모두 읽을 때까지 블록을 조회한다. 모두 읽었다면 close 를 통해 닫아주어야한다.
참고 사이트 : http://hadooper.blogspot.kr/ http://socurites.com/hadoop/%EB%B2%88%EC%97%AD-%ED%95%98%EB%91%A1-%ED%8C%8C%EC%9D%BC-%EC%8B%9C%EC%8A%A4%ED%85%9C%EA%B3%BC-mr-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98
MapReduce
- Google에서 정보 검색을 위한 데이터 가공(색인어 추출, 정렬 및 역 인덱스 생성 등)을
목적으로 개발된 분산 환경에서의 병렬 데이터 처리 기법이자 프로그래밍 모델
- Map과 Reduce는 모두 입/출력으로 Key-Value
Map : (Key1, Value1) -> (Key2, Value2)
- (Key, Value) 쌍을 읽어 다른 (Key, Value)쌍에 대응
- (Key, Value)를 읽어서 이를 필터링 하거나, 다른 값으로 변환하는 작업을 수행
Reduce : (Key2, List Value) -> (Key3, Value3)
- Key2를 기준으로 취합된 value list를 읽어 집계된 값 value3를 출력
- Map함수를 통해 출력된 값들을 새 키 Key3를 기준으로 그룹화 한 후 집계연산을 수행한 결과를 출력
처리 흐름
- HDFS 상에 적재된 각 파일 조각들은 Mapper 태스크들에 할당
- Mapper들은 클러스터 상의 여러 노드들에 분산되어 있으며, 각기 청크 하나를 받아 Map 함수를 수행하고 그 결과를 Mapper가 수행된 노드의 로컬 디스크에 기록한다. Mapper 태스크의 작업이 끝나고 남아 있는 chunk가 있다면, 추가로 할당하여 처리하도록 한다.
- Mapper들은 선택적으로 combiner를 가질 수도 있다. 이는 Mapper가 key-value만을 출력하고 이를 Reducer가 복사, 분할 하는데 드는 I/O와 네트워크 대역폭을 절감하고자 각 Mapper가 출력한 key-value에 대해 미리 그룹화하고 집계 연산을 수행하도록 하는데 이용된다.
- 더 이상 처리해야 할 chunk가 없고 모든 Mapper가 정상 종료되었다면, Reducer 태스크를 수행한다.
- HTTPS를 이용해 여러 노드들로부터 Key를 기준으로 각 Reducer가 처리해야 할 Key-Value를 이전 Mapper들의 로컬 디스크로부터 읽어 온다.
- key값을 기준으로 정렬 연산을 수행, 정렬된 key-value들을 동일 키 값을 기준으로 그룹화를 수행
- 각 key값을 기준으로 그룹지어진 값들을 대상으로 집계 연산을 수행하고, 그 결과를 다시 HDFS상에 출력.
데이터 처리 중 장애 발생
- Mapper의 경우 같은 청크를 대상으로 다시 수행하거나, 또는 유휴한 다른 Mapper가 해당 청크를 수행
- Reducer의 경우 Mapper의 결과는 이미 로컬 디스크에 Mapper의 결과가 실체화된 상태이므로 Mapper의 수행은 건너뛰고 Reducer 작업을 다시 수행.
- 파일의 내구성은 HDFS의 데이터 복제에 의존
위 글을 읽고 다음 그림을 보면 이해하기 쉬울것입니다.
학회지 CACM에 두 진영(DBMS와 MapReduce)이 주장하는 MapReduce의 장단점 요약 - http://bart7449.tistory.com/276 이 분께서 번역을 너무 잘해주셨습니다.
장점
- 단순하고 사용이 편리
- Map함수와 Reduce함수 라는 두 개의 함수를 구현함으로써 병렬 처리가 가능하게 한다는 것.
- 데이터의 분산 배치와 실행은 스케쥴러가 담당함으로써 사용자는 분산 시스템의 물리적 구조를 알지 못해도 데이터 병렬화 방식을 통해 분산 처리를 매우 쉽게 할 수 있다는 이점
- 유연성
- 특정화된 데이터 모델이나 스키마 정의, 질의 언어에 의존적이지 않다.
- 범용의 프로그래밍 언어를 이용하여 데이터를 어떻게 처리할지 기술
- 관계형 데이터 모델로는 표현되기 어려운 다르거나, 비 정형적인 데이터 모델들도 지원
- 저장 구조와의 독립성
- 병렬 데이터 처리를 위한 시스템으로 하부 저장구조와 독립적
- 기본적으로 HDFS와 같은 분산 파일 시스템 상의 파일을 입출력으로 하지만, 그외 일반 파일 시스템이나 DBMS등 다른 저장 구조를 하부에 두는 것도 가능
- 내고장성
- 분산 파일 시스템의 replication에 기반한 데이터의 내구성 지원과 함계 Mapper나 Reducer의 태스크 장애 시 각 태스크의 재수행을 통해 장애로부터의 내고장성을 확보한다.
- Map과 Reduce 작업이 처음부터 다시 실행되는 것을 막기 위해 Map의 결과는 Mapper가 수행된 노드의 로컬 디스크에 기록
- 높은 확장성
- 처리해야 할 데이터 크기가 커지면 그 만큼 높은 작업처리량을 가지도록 시스템을 개선
- 기존의 방식은 HW성능의 개선을 통해 처리량을 향상 시키는 scale-up방식
- MapReduce는 저가의 범용 PC들을 추가로 할당함으로써 확장성을 지원하는 scale-out 방식의 구현을 용이하게 한다.
단점
- 고정된 단일 데이터 흐름
- 이항 연상자를 지원하지 않는다.
- 때문에 join은 하나의 MapReduce 작업으로 표현되지 못하고 여러개의 MapReduce 작업을 직렬로 연결해 표현해야 한다.
- Loop는 매 반복때마다 계속 입력을 반복해서 읽어야 하는 등의 I/O 낭비가 심하다.
- 즉 MapReduce에서는 DAG(Directed Acyclic Graph) 형태로 자신의 워크플로우를 따로 적의하는 작업은 불가능하며, 복잡한 알고리즘의 구현을 위해서는 여러 번의 MapReduce 작업을 수행해야하는 불편함과 그에 따른 성능 저하가 많다.
- 스키마, 인덱스, 고차원 언어 등의 미지원
- 기존의 DBMS가 제공하는 스키마나 질의 언어, 인덱스 등을 제공하지 못한다.
- 데이터의 무결성의 미비는 결국 프로그램 로직 상에서 무결성을 검증하도록 하게 한다.
- 프로그램의 복잡성이 높ㅍ아지며, 하부 데이터 형식의 변경은 프로그램 조직의 변경을 야기하고, 또한 질의 형식의 재활용이나 손쉬운 질의의 작성을 어렵게 한다.
- 인덱스는 질의 처리 성능의 향상을 위해 중요하지만, MapReduce는 지원하지 않으며, 데이터의 일괄 처리만을 제공
- 단순한 스케쥴링
- 런타임 스케쥴링에 기반
- 런타임 스케쥴링에서는 태스크를 수행하는 경우는
- 1. 실패한 태스크를 재수행
- 2. 아직 수행되지 않는 태스크를 수행
- 3. 태스크가 매우 느린 경우
- 특히 3 의 경우는 임계값을 설정해 두고 일정 시간동안에 임계값을 도달하지 못하는 경우 strggler로 판정하고, 이를 다시 수행시키는데 노드 PC 성능이 상이한 경우 이 과정이 효과적이 못하다.
- 한 클러스터에서 여러 MapReduce 작업을 동시에 수행하는 경우에 대해서 효과적인 다중 작업 스케쥴링을 제공하지 못한다.
- 상대적으로 낮은 성능
- 성능 측정은 대개 단위 시간당 작업 처리량이나 시스템의 효율성 등으로 측정
- MapReduce는 다른 병렬 DBMS에 비해 데이터 적재 시간 이외에 우수한 성능을 보이지 못함
- 이러한 늦은 성능은 내고장서 지원을 위해 디스크 I/O를 희생하는 태생적인 이유에 근거
- 파일을 보관하는 분산 ㅍ파일 시스템은 2개의 replication를 추가로 가짐에 따라 디스크 공간과 I/O를 소비
- 복제된 이휴 읽기 연산은 각기 다른 복사본에 접근함으로써 병렬화를 꾀할 수는 있지만, 출력의 경우 한 데이터를 가지고 여러 노드에 분산, 기록.
- 각 태스크는 수행 결과를 다음 태스크에 전달하기 이전에 태스크를 수행한 노드의 로컬 디스크 또는 분산 파일 시스템 상에 기족하는 과정을 먼저 수행.
참고 사이트 : http://bart7449.tistory.com/276 다음 글은 MapReduce를 사용하여 Hello World인 WordCount를 구현하도록 하겠습니다. 구현 하면서 동작되는 원리를 정리해 볼까 합니다.