정보공간_1

[3기 신촌 윤기백] Hadoop의 이해 2편 - MapReduce의 소개및 이해 본문

IT 놀이터/Elite Member Tech & Talk

[3기 신촌 윤기백] Hadoop의 이해 2편 - MapReduce의 소개및 이해

알 수 없는 사용자 2013. 2. 5. 13:51

안녕하세요신촌멤버십 22-1기 윤기백입니다.


연재식으로 진행하고 있습니다.  이번에는 2화 Map-Reduce의 소개와 이해입니다. 

1화 - BigData의 정의와 HDFS

2화 - Map-Reduce에 대한 소개 및 이해

3화 - 실제 프로젝트와 함께 적용해보는 Map-Reduce

4화 - Hadoop의 Eco System 및 정리(예정)


Hadoop Map-Reduce의 소개

 

 Map-Reduce는 간단히 말하면 HDFS의 파일을 처리(분석)하기 위한 프로그래밍 모델이라고 할 수 있습니다.

 

 정확히 말하면, 흩어져 있는 데이터를 수직하여, 그 데이터를 각각의 종류 별로 모으고(Map), Filtering 

Sorting을 거쳐, 각각의 개수를 뽑아내는(Reduce) 분산처리 기술과 관련 프레임워크를 의미합니다.

이 때 단순히 개수만이 아니라 추가적인 연산 작업으로 더 다양한 의미있는 분석 결과를 뽑을 수 있습니다.

 

 Map은 흩어져 잇는 데이터를 Key, Value의 형태로 연관성 있는 데이터 분류로 묶는 작업

Reduce Map화한 작업 중 중복 데이터를 제거하고 원하는 데이터를 추출하는 작업입니다.



①  MapReduce로의 Input

Input File

-      HDFS에 저장되어 있는 파일들을 불러와서 Map Reduce를 진행합니다

Input Format

-       HDFS에 저장되어 있는 Input file을 한 줄씩 불러와서 맵 리듀스를 진행하게 됩니다.

 

Input Format

설명

Key

Value

TextInputFormat

데이터를 한 줄씩 불러옴

라인의 'byte offset'

라인의 내용

KeyValueInputFormat

Key Value로 나누어 데이터를 불러옴

첫 번째 탭 까지

라인의 나머지 부분

SequenceFileInputFormat

사용자가 정의해서 사용가능

사용자가 정의

사용자가 정의

Input Splits

-       하나의 파일을 정해진 파일 처리 단위로 나누어 줍니다. Input Format 'TextInputFormat'이거나 'KeyValueInputFormat'인 경우에는 한 줄 씩 나누어주는 역할을 합니다.

RecordReader(RR)

-       나누어진 파일 처리 단위를 Input Format에 따라 (Key,Valeu)의 형식으로 정형화 하여 줍니다. 이런 형식으로 데이터를 구성한 뒤에 Map() 메소드를 지속적으로 불러와서 실행시키게 됩니다.

 

② Mapper

 



 위의 그림처럼입력 받은 데이터를 분석하여 새로운 Key Value 값을 갖는 형태로 구성한 뒤, OutputCollector라는 객체에 담아서 반환하게 됩니다. Record Reader로부터 데이터를 한 줄씩 입력 받게 되고, 한 줄의 데이터를 입력받아 하나 또는 여러 개의 (Key, Value) 결과값을 생성하게 되는 것입니다. 이 때, 입력받은 하나의 (Key, Value) 데이터에 대해서 Map 과정을 수행하고 결과값을 생성하기 때문에 분산되어 있는 데이터를 옮기지 않고 저장 되어 있는 Node에서 바로 처리가 가능합니다. 그리고 입력받은 하나의 (Key, Value) 데이터만으로 결과값을 생성하므로 다른 데이터와 연관된 정보는 Map과정에서는 얻을 수 없습니다.

 

③ Partition & Shuffle, Sort

 Map 과정이 끝나고 나온 결과 데이터는 여러 개의 노드에 무질서하게 존재 하게 됩니다. 이 결과 데이터들을 Key에 따라 나누어서 Reduce 메소드를 진행하게 될 Node로 보내게 되는데 이 과정을 Shuffling이라고 합니다. 그리고 Map 의 결과로서 나오게된 중간 (Key, Value) 세트를 Partition이라고 합니다.

 정해진 키 값을 가진 데이터들이 Reduce 메소드가 진행 될 slave node로 옮겨진 뒤, Reduce는 같은 Key값을 같은 데이터를 모아서 처리하게 되는데 이를 위해서는 sort과정이 필요하게 됩니다. sort까지 마친 데이터들이 Reduce로 넘어가서 진행되게 되는 것입니다.

 

④ Combiner




 Combiner Mapreduce 파이프라인에서 Map Partitioner 사이에 존재합니다. Combiner는 꼭 필요한 기능은 아니지만 적절히 사용하면 성능 향상에 큰 도움이 될 수 있습니다. Combiner map에서 나온 결과 데이터를 Reduce와 같은 방식으로 같은 Key를 갖는 데이터들을 입력받아 원하는 결과를 만들어 낼 수 있습니다. Reduce와의 차이점은 한 Node에서 일어난 map의 결과에 대해서만 실행되기 때문에, Combine 만으로는 원하는 결과를 얻을 수 없다는 점입니다. 하지만 분산되어 처리되는 Combiner Reduce의 계산량을 많이 줄여 줄 수 있습니다.


⑤ Reducer



 Redeuce Key값이 같은 모든 정보들을 Input으로 갖습니다. 같은 Key값을 같는 모든 데이터를 리스트의 형태로 입력 받은 뒤 이들의 조합에서 원하는 결과를 분석할 수 있습니다. 또한 Output 데이터는 한 개 또는 여러개의 (Key, Value)형식 또는 다양한 형식으로 만들어 낼 수 있습니다.


⑥ MapReduce로부터의 Output

OutputFormat

- OutputCollector 객체에 담겨져 있는 데이터들을 정해준 형식에 따라 미리 정해준 경로에 파일 형식으로 저장하게 됩니다. Output파일 형식은 다음 표와 같이 3가지 형식이 있습니다.

   

OutputFormat

설명

TextOutputFormat

"Key \t Valeu"의 형식으로 Output을 출력

SequenceFileOutputFormat

사용자가 정의한 형식으로 Binary file 형식으로 출력

NullOutputFormat

Disregards its inputs

TextOutputFormat 형식으로 결과 파일을 생성할 경우에 TextInputFormat으로 연속으로 다음 Map-Reduce과정을 실행 할 수 있다는 장점이 있습니다.


 자, 이제 Map-Reduce의 실질적으로 Hadoop에서 어떻게 동작하는지 알아보도록 하겠습니다

 그 속의 과정을 이해하셔야 Map-Reduce를 효과적으로 사용할 수 있습니다.



위의 그림은 Hadoop에서 Map-Reduce를 진행하는 과정입니다.

하나씩 과정을 살펴보면 다음과 같습니다.


1)    맵리듀스 프로그램에 의해 실행된 작업은 JobClient runJob() 메소드에 의해 새로운 JobClient 인스턴스를 생성하고 submitJob() 메소드를 호출합니다.


2)    submitJob()메소드 그림의 2,3,4과정을 진행합니다. 즉 잡트래커에 새로운 잡ID를 요청(getNewJobId() 메소드 호출)합니다. 잡의 명세를 확인하고 잡에 대한 입력 스플릿들을 계산합니다. 잡 수행에 필요한 자원들인 잡 JAR 파일, 설정파일, 입력 스플릿 정보들을, 해당 잡ID를 이름으로 하는 디렉터리에 복사합니다. 마지막으로 잡트래커가 잡을 시작할 준비가 되었음을 알립니다.


3)    잡 초기화단계(5단계)에서는 잡을 큐에 넣고, 잡 스케쥴러는 그것을 가져가서 초기화합니다. 또한 수행할 태스크 목록을 생성하기 위해, 잡 스케줄러는 3단계에서 저장된 입력 스플릿들을 가져오게 됩니다.(6단계)


4)    그리고 태스크트래커는 heartbeat를 주기적으로 호출하여 잡트래커에 보내는 단순 루프를 수행합니다. 잡에는 우선순위가 존재하며, 이는 스케줄링 알고리즘에 의해서 수행되게 됩니다. (여기서 스케줄링 알고리즘은 다양하게 존재합니다)


5)    이어서 태스크트래커노드에서 JVM을 실행하고, 각 잡이 이 JVM에서 수행하게 됩니다.

 

간단히 설명했지만, 사실 좀 더 복잡한 흐름을 갖게 됩니다. 일단 기본적인 흐름을 숙지하신 후에, Hadoop 

Document 혹은 책을 통해서 자세히 이해하시길 바랍니다.



Map-Reduce, WordCount 예제

 

 

 

 이제 Hadoop을 설치하면 기본으로 존재하는 WordCount 예제를 통해서 실제 사용이 어떻게 되는지 설명하도록


 하겠습니다. ( $HADOOP_HOME/src/examples/org/apache/hadoop/examples/WordCount.java)

 

 WordCount예제는 MapReduce Framework를 이해할 수 있는 가장 기본이 되는 예제입니다.


 여기까지 접근은 쉽게 하지만 이를 응용하는 것이 어렵습니다. 그외 다른 기본 예제를 확인하시고


 다음에 진행하게될 MapReduce의 활용편을 보시면서 프로젝트에 어떻게 적용되는지 본다면 좋을 것 같습니다.


 

 WordCount예제는 input data로 각각의 row에 하나의 word가 있을 때, word의 개수를 알아내는 예제입니다


 예를 들면 다음 그림과 같습니다.

 


 이를 map과정을 통해 흩어져있는 모든 input word를 나열하게 됩니다. 각각의 count 1로 맵핑되고


 최종적으로 reduce과정을 거쳐서 각각의 단어의 개수를 알 수 있게 됩니다.




 

  

소스를 통해서 확인해보겠습니다.

 

WordCount Class내에는 두개의 inner 클래스가 존재하게 됩니다. 우선 TokenizerMapper라는 


Mapper 클래스와 IntSumReducer라는 Reducer클래스가 그것입니다.



각 클래스는 크게 어렵지 않습니다.


 

Mapper클래스로부터 map 메소드를 오버라이딩하여 재구성합니다


value라는 파라미터를 통해 자신에게 할당된 input data를 받고 이로부터 word마다 1이라는 값과 함께


-밸류로 묶어 context write하게 됩니다


즉 중복된 word를 생각하지 않고, 모든 word를 나열한다고 생각하면 될 것 같습니다.



 


 

Map과정이후에 Reducer 클래스의 reduce 메소드를 호출하여 reduce과정을 진행하게 됩니다


간단히 소스에서도 알 수 있듯이, 해당 key와 맵핑된 values값들을 더해주는 것을 확인할 수 있습니다.


여기서 의문점이 발생해야 됩니다. Mapper에서는 단순히 각 단어와 1을 키밸류로 매칭하여 결과를 


context에 저장하고 있었습니다. 하지만 Reducer에서는 key값과 1을 요소로 가지는 


Iterables<IntWritable>인 리스트형태가 되었습니다.



, Map과정에서 진행된 결과가 Reduce 함수로 반환될때는 다시 Word를 가지고 하나로 묶이게 됩니다.


아래 그림을 보시면 이해하실 수 있을 것입니다.

 

reduce 동작이 작동하면 “hadoop”이라는  word와 같이 <1,1>이라는 리스트형태로 파라미터로 넘어가게 되고, 이를 reducer가 처리하게 되는 것입니다.

최종적으로 다음과 같이 실행하여 우리가 원하는 결과를 얻을 수 있습니다

최종 결과파일입니다.  각 단어가 Count되었음을 확인하실 수 있습니다.


이번엔 Map-Reduce에 대해서 소개와 간단한 WordCount예제를 소개해드렸습니다. 

어느정도 Map-Reduce에 대해서 감이 오셨을 것이라고 생각합니다만, 혹시 궁금하신 점 있으면 연락주시기 바랍니다. (E-mail : seseki17@gmail.com)


다음에는 실제 저희 팀의 프로젝트를 예시로 Map-Reduce 응용을 설명해보겠습니다.


참고 자료/사이트 : http://hadoop.apache.org/

http://bicdata.com

Hadoop 완벽가이드 - 한빛미디어


감사합니다.