[Data Engineering] Hadoop - 하둡, HDFS, MapReduce
📌 목차
- 하둡이란?
- 하둡의 특징
- 하둡의 발전
- 하둡 배포판
- 하둡 라이센스
- 하둡 작업 모델
- 하둡의 문제점
- HDFS
- HDFS 구조
- HDFS Data 읽기
- HDFS Data 쓰기
- HDFS 액세스
- MapReduce
- MapReduce JobTracker
- MapReduce Job/Task
- MapReduce Scheduler
- MapReduce 사용 적합 분야
- MapReduce 사용 부적합 분야
🍀 하둡이란?
대용량 데이터를 분산 처리해줄 수 있도록 해주는 아파치 톱 레벨 오픈소스 프로젝트이다.
소프트웨어 프레임워크이며, 자바로 구현되어 있다.
Nutch/Lucene 프로젝트의 하위 프로젝트로 시작하여 2006년 독립 프로젝트로 분리되었다.
크게 분산파일시스템(HDFS)과 분산처리시스템(MapReduce)으로 구성된다. 하둡은 HDFS가 데이터를 저장하고, MapReduce가 저장된 데이터를 기반으로 데이터를 처리해주는 프레임워크이다. HDFS는 여러 노드로 구성되어 있는 파일 시스템이라고 생각하면 된다.
이밖에도 하둡커몬이라고 불리는 여러 라이브러리들도 구현되어 있고, 하둡의 일부이다.
🍀 하둡의 특징
데이터가 있는 곳으로 코드를 이동한다. MapReduce나 기타 다른 계산 프레임워크에도 다 적용된다.
기존 계산 프레임워크들을 대부분 계산 서버가 있으면, 계산을 빨리 할 수 있는 서버(고사용 CPU 장착된)에 파일 시스템에 있는 데이터를 옮겨서 계산 서버에서 처리하는 형식으로 구성되어 있었다.
여기서는 그게 아니라, 데이터가 분산되어 있다. 계산을 할 수 있는 코드를 각각 대상이 되는 노드로 전달해서 파일에 대해 계산해서 결과를 모으는 식으로 구성된다. 일반적으로 코드는 데이터의 사이즈보다 작을 것이다. 데이터를 코드로 보내는 게 아니라, 코드를 데이터로 보낸다. 이게 핵심이다.
소수의 계산을 빠르게 하기 위한 비싼 서버 보다는 다수의 저렴한 서버를 사용할 수 있다. 가성비가 우수한 서버를 여러 개 사용하여 계산할 수 있다. Scale-Out 접근방식이다.
데이터 모델이 단순하다. MapReduce에서는 단순한 데이터 모델을 key-value의 변화로 계산해낸다. 빅데이터를 처리하는 알고리즘을 구현하게 되는 것이다. 데이터의 locality(국지성)을 최대한 이용한 프로그래밍 모델이다.
오프라인 배치 처리에 최적화되어 있다. 실시간 처리가 아닌.
HDFS는 하나의 Name Node(마스터)와 하나 이상의 Data Nodes(슬레이브)가 있다. Name Node는 파일 시스템의 파일 구조도를 관리하는 역할을 한다. Data Nodes는 실제 파일의 내용을 관리한다. Secondary NameNode는 주기적으로 Name Node의 내용을 백업 받고 snapshot을 남기는 역할을 한다.
MapReduce는 하나의 Job Tracker(마스터)와 여러 개의 Task Trackers(슬레이브)가 있다. Job Tracker는 전체 Job을 관리하는 서버이고 Task Trackers는 실제 MapReduce Task들을 실행시키고 종료하는 그런 역할들을 한다.
대부분 경우 이 둘은 한 물리적인 클러스터에 공존한다. Name Node/ Job Tracker가 같이 살고, Data Node/ Task Tracker가 같이 동거하고 있다고 생각하면 된다. 데이터가 분산되어 저장되어 있으면, 계산을 위한 코드가 데이터로 전송돼서 실행된다. 그게 가능하려면 Task Tracker들이 같은 노드에서 실행된다고 생각하면 된다.
🍀 하둡의 발전
2005년 Doug Cutting이 Nutch 크롤/검색 패키지에 구글페이퍼를 기반으로한 HDFS/MapReduce 프레임워크를 추가하면서 시작되었다.
2006년 Doug Cutting 야후 검색팀에 조인하고 20 노드 클러스터를 셋업했다. 하둡이 Nutch에서 떨어져나와 아파치 톱레벨 프로젝트로 변신했다.
2008년 야후에서 1000 노드 하둡 클러스터를 프로덕션에서 사용하기 시작했다. 2012년 하둡 생태계가 활발히 커가고 있다.
🍀 하둡 배포
대표적으로 Cloudera, HortonWorks, MapR등의 회사도 하둡 배포판을 만들고 있다. 이 배포판들은 모두 오픈소스이고 개인 사용 시 무료이다. MapR 배포판은 AWS ElasticMapReduce도 있다. 아마존에도 하둡이 들어가있다. VMWare 가상화버전의 하둡 이미지를 런칭했다.
🍀 하둡 라이센스
아파치 라이센스이고, 무료 소프트웨어 라이센스이고, 내부적으로 사용 가능하고 재배포하거나 심지어 파는 것까지 가능하다.
🍀 하둡 작업 모델
하둡 자체는 아파치 소프트웨어 재단의 소유물이다. 아파치 재단은 비영리조직이다. 하둡 소스코드나 소프트웨어가 발전하는 형태는 다음 4가지 형태의 contribution에 의해 진행된다.
- 사용자(대부분) : 다운받고 설치하고 실행하고 개발한다. 사용자가 기여할 수 있도록 되어있다.
- contributor : 패치생성, 버그 리포트, 문서 작성 등을 한다.
- committer: contributor의 작업을 반영할지 말지를 결정한다.
- PMC - Project Management Committee : 새 릴리스와 committer 선정 투표한다.
🍀 하둡의 문제점
오픈소스인 게 문제이다. 너무 많은 버전과 부실한 서포트이다. 3rd Party 배포판이 인기가 높은 이유이다. 특히 MapR에서 만든 하둡은 AWS에서 사용할 수 있다.
셋업과 사용이 쉽지 않다. 스킬셋을 가진 사람이 많지는 않아서 그런데 최근에는 늘어났다.
하둡에 맞지 않는 작업도 존재한다. 소규모이거나 대용량의 데이터 처리가 필요하지 않다면 하둡으로 옮겨갈 이유가 없다.
🍀 HDFS
2003년 구글랩에서 발표된 The Google File System이란 논문을 바탕으로 작성된 파일 시스템이다.
큰 파일을 여러 개의 블록으로 나눠 저장하고, 그 블록 사이즈를 64MB로 한다.
하드웨어 고장에 견고한다. 견고함을 위해 하나의 데이터 블록을 세군데 서버에 저장하며, 같은 rack에 있는 서버들에 2개를 저장하고 다른 1개는 다른 rack에 있는 서버에 저장한다.
- rack은 서버를 쌓아둔 장치이다. 같은 rack 안에 데이터 블록을 2개 저장하고, 다른 rack 서버에 1개 저장한다. 이렇게 설계 하는 이유는 한 rack이 고장나면 수행 중이던 코드를 같은 rack에 있는 다른 서버로 옮겨서 처리할 수 있도록 하기 위함이다. 같은 rack이란 것은 네트워크가 가깝고 코드 이전이 쉽다는 것이다. rack이 고장나면 다른 rack에서 처리할 수 있도록 3개의 copy가 존재한다.
Write Once Read Many. 쓰기는 한 번만 읽기는 여러 번 일어난다.
- 빅데이터는 한 번 쭉 써지고 나서 군데군데를 업데이트 하는 일은 발생하지 않고, 여러 번 읽는 일은 발생한다는 특징이 있다. 이 특징을 바탕으로 블록 사이즈를 64MB로 했다. 윈도우 파일 시스템 블록 사이즈를 64MB로 하면, 1MB PPT를 저장하려면 기본 저장 사이즈를 위한 LOSE가 생긴다. 1MB 속 1B를 수정하더라도 전체 64MB를 업데이트해야 하는 단점이 있다. 윈도우나 리눅스 파일 시스템의 기본 블록은 4KB이다. 업데이트는 안되지만, Append 작업은 가능하다. 내용을 바꾸기 위해 업데이트를 하려면 파일 전체를 새로 써야한다. 근데 내용 업데이트 많이 발생하지 않는다.
스트리밍 데이터 엑세스가 가능해서 배치 Job에 최적화 되어있다.
MapReduce나 HBase와 같은 시스템의 기본 구성 블록으로 사용할 수 있다.
계층 구조의 파일 시스템을 제공한다.
🍀 HDFS 구조
NameNode는 HDFS마다 단 하나만 존재한다. 마스터 노드로서 저장되는 각종 파일들의 메타 정보를 관리하고 실제 데이터는 다수의 DataNode에 분산 저장된다.
- Rack awareness. rack의 configuration을 가지고 있어서 3 copy를 유지할 수 있도록 관리하는 역할을 한다.
- DataNode들의 계속적으로 통신을 주고받는다. (Heartbeat) 어느 특정 시간만큼 Heartbeat 메세지를 주고받지 못하면 해당 DataNode는 fail로 표시하게 되고 관리되는 블록을 다른 곳에서 관리될 수 있도록 마이그레이션한다. Dead node에 저장된 데이터는 사용할 수 없어서 일시적으로 2 copy가 된다. 3 copy를 만들어주기 위해서 다른 노드들에 복사를 한다.
NameNode의 단점으로 A single point of failure이 있다. NameNode 자체가 파일/디렉토리의 구조를 담고 있고, 메타정보를 담고 있기 때문에 NameNode가 failure되면 갖고 있던 정보에 접근할 수 없어서 전체 하둡 클러스터의 HDFS 클러스터로의 접근 방식이 사라진다.
🍀 HDFS 상에서 Data 읽기
- 클라이언트는 실제 데이터를 읽거나 쓰고자 하는 프로세스라고 생각한다. 클라이언트가 파일을 읽는다는 것은 파일에 대한 경로 정보를 알고 있다는 것이고, 그 경로 정보를 먼저 NameNode에 전달한다. NameNode는 경로 정보를 이용해서 DataNode의 위치를 다 받아온다. NameNode와 통신하여 해당 파일의 데이터 블록 위치 리스트(DataNode와 블록ID)을 얻는다.
- 클라이언트는 위 데이터를 수신하게 되면 DataNode들과 직접 통신하여 블록데이터들을 차례대로 읽어들일 수 있다.
🍀 HDFS 상에서 Data 쓰기
- 클라이언트는 HDFS 파일을 생성하고자 하면, 먼저 로컬 파일 시스템에 파일을 생성한다.
- 파일 생성이 끝나거나 크기가 데이터 블록의 크기보다 커지면, 이때 NameNode와 통신한다. 클라이언트는 생성한 파일의 경로 정보를 바탕으로 NameNode에 파일 생성 요청을 보낸다.
- NameNode는 Replication factor(예를 들어3)만큼의 DataNode와 블록ID를 클라이언트에게 전송한다.
- 클라이언트는 받은 데이터 중 첫번째 DataNode에 데이터를 쓰면서, replication이 일어나야 하는 나머지 DataNode들의 리스트를 같이 넘긴다. 클라이언트가 네트워크 상으로 3개의 서버보다 네트워크 상으로 멀다는 가정이 깔려있다.
- 첫번째 DataNode는 데이터를 복제받으면서 두번째 DataNode로 복제를 시작한다.
- 마지막 DataNode에서 블록의 복제가 완료되면, 이 시점에서 해당 데이터 블록의 생성은 완료된 것으로 간주된다. 이 프로세스를 Replication pipelining이라고 한다.
- 더 써야할 데이터가 있으면 다시 3으로 가서 반복한다.
File 자체는 원격에 있다. 내가 쓰고 있는 pc에 있는 게 아니라 빅데이터는 원격에 있다. 원격 서버에서 실제 데이터를 갖고 계산도 할 수 있는 게 하둡의 개념이다.
🍀 HDFS 액세스
셀 커맨드를 이용해서 할 수 있다. DFS 어드민 기능도 제공한다. 예를 들어 format 기능이 있다.
로컬에서 이런 명령어를 수행할 수 있지만, 실제 이런 명령이 영향을 미치는 것은 원격에 있는 하둡 클러스터이다. 내가 사용하는 pc에서 일어나는 일이 아니다.
🍀 MapReduce
MapReduce 프레임워크는 일종의 대규모 분산 Merge-Sorting 프레임워크이다.
MapReduce로 코드/프로그램을 작성하는데, 데이터가 있는 서버로 코드를 전송한다. 데이터가 있는 노드에서 데이터를 처리하도록 되어있다.
데이터프로세싱(처리)을 key-value 데이터셋의 변환으로 진행한다. mapper와 reducer.
Shared Nothing 아키텍처. 하드웨어적으로는 서버들 사이에 공유하는 것이 단 하나도 없다.
- 물리적인 리소스를 공유하는 것이 없다. 서버들 사이에 메모리를 공유하지도 않고, SSD 같은 디스크, CPU도 공유하지 않는다. 다만, 네트워크로 연결되어 메세지만 주고받는 아키텍처이다.
- MapReduce 프레임워크에서 동작하는 모든 프로세스들은 map과 reduce이다. 이 두 과정을 코드로 작성하게 되고, 이 아키텍처 관점에서 봤을 때는 map 프로세스들, reduce 프로세스들끼리도 공유하는 것이 없다. map, reduce들끼리 공유하는 것은 없고 map과 reduce는 메세지를 전달한다.
Data locality(국지성)을 최대한 활용한다.
- 데이터 쪽으로 코드를 보내는데, 2 copy는 1개의 rack에 있고 또 다른 copy는 다른 rack에 있다. mapper를 실행할 서버를 찾을 때 입력 파일 블록을 이미 갖고 있는 서버나 그 서버와 같은 rack에 있는 서버를 찾으려고 한다.
클라이언트가 map/reduce를 생성하고 이 코드를 JobTracker에게 보내 요청한다. JobTracker는 TaskTracker들의 상태를 보고 스케줄링을 시작한다. 여유 있는 서버에 map, reduce를 차례로 보낸다. reduce 작업까지 끝나면 결과가 다른 HDFS 파일로 저장이 된다.
🍀 MapReduce JobTracker
JobTracker는 MapReduce 프레임워크의 마스터로서 한 클러스터에 하나만 존재한다. NameNode와 마찬가지로 A single point of failure에 취약하다.
MapReduce 프레임워크에서 실행되는 모든 Job들의 실행을 관리한다.
- 사용자로부터 하둡 잡 실행 요청을 받아서 클러스터 내의 TaskTracker가 Job을 실행할 수 있도록 한다. 실행요청이 Job 스케줄러로 들어가고, JobTracker는 스케줄러로부터 다음 실행할 Job을 얻는다.
- 태스크들이 종료될 때까지 관리하며 만일 특정 태스크가 실패하면, 다른 TaskTracker에 그 태스크를 다시 실행하도록 한다.
- 보통 JobTracker는 HDFS의 마스터의 NameNode와 같은 서버에 위치하도록 설정된다.
- TaskTracker는 HDFS의 DataNode들과 같이 공존한다.
- 하둡 쉘커맨드와 웹 인터페이스를 통해 Job/Tasks들의 상태를 볼 수 있다.
TaskTracker는 주기적으로 JobTracker에 상태보고 (Heartbeat) 메세지를 전달한다. failure되면 다른 노드에서 실행될 수 있도록 한다.
- 실행 중인 태스크가 mapper의 경우 입력 레코드들의 처리 퍼센트를 알려주고, reducer인 경우는 셔플링/소팅/그 이후로 나눠서 알려준다.
🍀 MapReduce Job/Task
Job은 MapReduce 프로그램 전체를 의미한다. JobTracker가 관리한다. Task들은 보통 하나의 Job에서 실행되는 mapper, reducer로 구성되며 이 mapper들과 reducer들을 말한다.
- 각각의 Task는 TaskTracker가 관리하고, 각 Task는 자바 VM에서 실행된다.
- 실패한 Task는 JobTracker에 이해서 다른 노드에서 재시도된다.
- Speculative Executaion : JobTracker의 기능이기도 하다. 아직 TaskTracker가 완전히 실패한 것은 아닌데, 굉장히 느리게 돌아갈 수 있다. 서버 디스크 성능이 낮으면 mapper가 디스크에서 데이터를 읽어서 Task를 실행하는데 엄청 느릴 수 있다. 느리지만 정상 동작인 것인데, JobTracker는 그 Task에 대해 보상하기 위해 다른 노드에 같은 일을 하는 Task를 런칭한다.
하나 이상의 Job들을 엮어서 실제로 원하는 일을 수행하게 되는 경우가 대부분인데, 이런 것을 하둡 Job Chaining이라고 하고 워크플로우 관리가 굉장히 중요하다. Oozie를 많이 사용한다.
🍀 MapReduce Scheduler
Scheduler는 Task를 스케줄링 하는 것이다. 어느 노드에게 어떤 순서로 수행하게 할지 정하는 것이다. 기본적으로 FIFO 스케줄링을 지원한다. 들어온 순서대로 실행되는 스케줄러이다. 플러그인 형태라 커스텀 스케줄러의 개발이 용이하다.
- Job 제출 시 Job의 우선순위를 정해줄 수 있지만 실행 중인 Job의 pre-emption은 불가하다.
- Job 하나가 전체 클러스터의 리소스를 독점할 수 있다.
🍀 MapReduce 사용 적합 분야
- 병렬도가 높은 Jobs ( no dependency )
- 로그 분석
- 머신 러닝, 데이터 마이닝
- ETL
🍀 MapReduce 사용 부적합 분야
- 리얼타임 데이터 처리
- 리얼타임 데이터 엑세스
- 많은 반복이 필요한 작업들