'MapReduce'에 해당되는 글 5건

  1. 2016.01.20 하둡 맵리듀스 Join 활용 퀴즈!!
  2. 2014.08.25 BigData 처리를 위한 맵리듀스(MapReduce)에 대하여~
  3. 2014.08.15 Hive & Pig - 하둡(Hadoop)의 맵리듀스를 보다 편하게~
  4. 2012.05.25 하둡(hadoop) 맵리듀스 프로그래밍을 위한 이클립스 설정 및 맵리듀스 개발 #2 (3)
  5. 2012.05.22 하둡 맵리듀스 프로그래밍을 위한 이클립스 플러그인 설정 #1

하둡 맵리듀스 Join 활용 퀴즈!!

|



본 퀴즈는 University of California, San Diego의 Super Computer Center, Paul Rodriguez님의 강의에 포함된 내용이다. 

해당 퀴즈에 대한 답은 올려놓지 않을 계획이므로 아래 내용을 잘 따라하고 직접 풀어보기 바란다. 

하둡 맵리듀스 Join 활용 예제 를 참고하면 쉽게 구현할 수 있을 것이다. 


아래 예제에 따라 데이터 파일을 생성하고 조인하는 맵리듀스를 파이썬으로 구현해 보도록 하자. 


1. 퀴즈에 사용할 데이터 파일을 생성하는 다음 파이썬 소스를 make_join2data.py 파일로 저장한다. 


2. 파이썬 소스를 실행하는 스크립트를 make_data_join2.txt 파일로 만들고 이를 실행한다. 

> sh make_data_join2.txt


3. 생성된 데이터 파일을 살펴보자. 

join2_gennum*.txt 파일은 <TV show, count> 형태로 TV 프로그램과 시청수를 나타낸다. 


join2_genchan*.txt 파일은 <TV show, channel> 형태로 TV 프로그램과 해당 프로그램의 TV 채널을 나타내고 있다. 


4. 생성된 파일들을 HDFS에 올린다. 


5. 이제 다음 과제를 수행하는 맵리듀스를 구현해보자. 

"ABC 채널에서 방송되는 프로그램의 전체 시청자 수는 얼마일까?"

이 과제를 SQL 형태로 만들어보면 다음과 같다. 

select sum( viewer count) from File A, File B where FileA.TV show = FileB.TV show and FileB.Channel='ABC' grouped by TV show


최종 결과 파일의 앞부분 일부는 다음과 같이 나오면 된다. 


참고

하둡 맵리듀스 Join 활용 예제 를 참조해서 먼저 스스로 구현해 보고 잘 안될 경우, 아래 힌트를 참고해서 구현해 보기 바란다. 


join2_mapper.py 구현

read lines, and split lines into key & value
if value is ABC or if value is a digit print it out


다음 명령어로 결과값을 먼저 확인해 볼 수 있다. 

> cat join2_gen*.txt | ./join2_mapper.py | sort


join2_reducer.py 구현

read lines and split lines into key & value
if a key has changed (and it's not the first input)
then check if ABC had been found and print out key and running total,
if value is ABC then set some variable to mark that ABC was found (like abc_found = True)
otherwise keep a running total of viewer counts

다음 명령어로 결과값을 먼저 확인해 볼 수 있다. 

> cat join2_gen*.txt | ./join2_mapper.py | sort | ./join2_reducer.py


하둡 스트리밍으로 최종 명령어의 형식은 다음과 같다. 

hadoop jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar \
   -input /user/cloudera/input/join2*.txt \
   -output /user/cloudera/output_join2 \
   -mapper /home/cloudera/join2_mapper.py \
   -reducer /home/cloudera/join2_reducer.py





Trackback 0 And Comment 0

BigData 처리를 위한 맵리듀스(MapReduce)에 대하여~

|




맵리듀스 개요

맵리듀스(MapReduce)는 기존 하드웨어를 활용한 분산 프로그래밍 모델로서, 

대용량 데이터를 빠르고 안전하기 처리하기 위해 만들었다. 


2014년 OSDI 컨퍼런스에서 구글이 "MapReduce : Simplified Data Processing on Large Clusters" 논문을 발표한 이후, 

맵리듀스는 관심을 받기 시작했다. 


그리고 오픈소스 루씬(Lucene)의 개발자인 더그 커팅(Doug Cutting)이 하둡(Hadoop)을 만들면서 맵리듀스가 널리 알려졌다. 

하둡 오픈 소스 프로젝트는 구글의 분산 기술(GFS, MapReduce)을 기반으로 2006년부터 시작했다. 


하둡 파일 시스템(HDFS)는 대규모 분산 파일 시스템 구축의 성능과 안전정을 보여줬고, 

맵리듀스는 HDFS에 저장된 대규모 분산 파일에 대한 로그 분석, 색인 구축, 검색에 탁월한 능력을 발휘했다. 


이후, 아마존은 맵리듀스 플랫폼(Amazon Elastic MapReduce)을 클라우드 서비스로 제공하기 시작했고, 

몽고디비(MongoDB)와 같은 NoSQL에서도 MapReduce Operation을 제공했다. 


맵리듀스 - 발상의 전환

맵리듀스의 개념을 이해하기 위해, 먼저 기존 프로그래밍 방식을 생각해보자. 

첫째, 데이터를 가져온다. (Fetch Data)

둘째, 가져온 데이터를 처리한다. (Process Data)

셋째, 처리한 데이터를 저장한다. (Save Data)

기존 프로그래밍은 데이터를 가져와서 중앙에서 처리하고 다시 저장하는 구조다. 

하지만 대용량 데이터를 애써 분산 환경에 저장했는데, 처리를 위해 대용량 데이터를 다시 가져와야 한다니? 

즉, 데이터를 가져오는 비용이 많이 든다. 

그래서 데이터를 가져오지 않고 처리할 수 있는 '무엇'이 필요했다. 


이것이 바로 "맵리듀스"이다. 

발상 전환으로 데이터를 가져오지 않고, 데이터가 저장된 곳에서 처리할 수 있도록 만들었다. 

맵리듀스는 크게 맵(Map) 단계와 리듀스(Reduce) 단계로 나눈다. 

맵 단계가 바로 데이터가 저장된 로컬에서 동작한다. 


맵리듀스 이해 

맵 단계와 리듀스 단계 모두 입/출력으로 키-값(Key-Value) 쌍을 가진다. 

키와 값의 타입은 개발자가 선택하며, 맵 함수와 리듀스 함수도 개발자가 직접 작성해야 한다. 


맵리듀스의 단어수 계산(WordCount) 예제로 개념을 정리해 보자. 

"클라우드 컴퓨팅 용어의 정의는 무엇인가?"

"최근 클라우드 컴퓨팅이 화두가 되면서 애매모호한 용어로 인해"


위 두 문장의 단어를 세는 프로그램을 맵리듀스로 처리하면 다음과 같다. 



맵 함수의 입력은 다음과 같다 - 키: 줄번호(라인번호), 값: 문장(라인)

실제 키는 줄번호가 아니라, 파일 각 줄의 시작 오프셋(offset)이 된다. 


맵 함수에서는 각 문장을 공백으로 분류해 단어와 글자 수를 키-값 형태로 제공한다. 

그리고 정렬과 병합이 일어난다. 

여기까지가 분산 저장된 로컬 서버에서 일어나는 작업이다. 


리듀스 함수는 "단어-글자수 목록"을 입력으로 받아서, 각 단어들의 개수를 취합해 최종 결과를 제공한다. 


맵리듀스 구조

맵리듀스의 처리 과정을 한번 더 정리해 보자. 

대용량 입력 파일을 분리(Split)한 후, 맵 함수를 적용한다. 

그리고 리듀스 함수에 전달하기 위해 셔플링(Shuffling)이 일어나고 최종 결과를 생성한다. 


하둡에서 최초 입력 파일은 먼저 스플릿(Split)해서 HDFS에 저장한다. 

대용량 파일을 한번에 처리할 수 없기 때문에, 적절한 크기로 잘라낸 후 맵리듀스로 처리하는 것이다. 

하지만 스플릿의 크기가 너무 작을 경우, 분할 관리 및 맵 태스트 생성의 오버헤드가 있어 역효과가 날 수 있다. 

보통 하둡에서 64MB 이상의 스플릿을 사용하도록 권장하고 있다. 

클라우데라의 CDH에서는 기본값이 128MB로 설정되어 있다. 


셔플링(Shuffling)은 맵 함수의 결과를 취합하기 위해 리듀스 함수로 데이터를 전달하는 역할을 한다. 

그 전에 맵 함수의 결과에 대해 정렬과 병합(Sort & Merge)이 일어난다. 

그리고 각 서버에 나뉜 데이터들을 키를 중심으로 합쳐서 리듀스 함수에 전달한다. 

이렇게 리듀스 함수로 데이터를 전달하는 것을 셔플링(Shuffling)이라고 한다. 


이제 파티셔너(Partitioner)와  컴바이너(Combiner)에 대해서 살펴보자. 

파티셔너는 맵 함수의 결과를 각 파티션으로 나누어 저장하는 역할을 한다. 

파티션을 나누는 기준은 키이며, 기본적으로 키에 해쉬 함수를 적용해 처리한다. 

위 그림에서도 맵 결과를 버퍼에 저장하다가, 디스크에 저장할 때 파티션, 정렬 등의 작업이 일어나는 것을 알 수 있다. 


컴바이너는 일반적으로 리듀서와 동일하게 사용한다. 

그래서 컴바이너를 "로컬 리듀서"라고도 한다.

왜 컴바이너가 필요할까?

맵리듀스는 대용량 처리를 위해 만들었다. 

맵 함수까지는 로컬에서 실행하지만 리듀스 함수로 데이터를 전달하는 것은 네트워크를 이용할 수 밖에 없다. 

로컬에서 리듀스 함수를 먼저 처리한다면, 네트워크로 전달하는 데이터 양이 대폭 감소할 것이다. 


리듀스 함수를 컴바이너로 사용하기 위해서, 리듀스 함수의 입력과 출력의 타입이 같아야 한다. 

그렇지 않을 경우, 별도의 컴바이너를 구현해서 활용할 수 있다. 


컴바이너 적용에 따른 차이는 다음 그림을 살펴보도록 하자. 

컴바이너를 적용함으로써 리듀스 함수로 전달하는 데이터 양이 조금 줄어든 것을 볼 수 있다. 

"뭐 이정도 쯤이야?"하고 생각할 수 있지만, 실제 대용량을 처리할 때 그 차이는 무시할 수 없을 것이다. 


빅데이터를 다룬다면, 맵리듀스의 개념과 구조 정도 이해해야 한다. 

맵리듀스 대신 Hive와 같은 기술로 처리하더라도, 개발자라면 내부적으로 어떤 일이 일어나는지 알아야 하지 않을까?


-- 2012년 2월 29일 처음 작성한 글을 재구성했습니다. 





Trackback 0 And Comment 0

Hive & Pig - 하둡(Hadoop)의 맵리듀스를 보다 편하게~

|



하둡(Hadoop) 프로젝트를 진행할 때 사람들의 고민이 무엇일까? 하고 생각해 봤습니다. 

Java 언어에 익숙하더라도 첫번째로 만나는 문제는 역시 맵리듀스(MapReduce)가 아닐까 합니다. 


맵리듀스는 맵과 리듀스가 합쳐진 것으로 각각의 Map 함수와 Reduce 함수를 구현하고 JobClient를 통해 호출해야 합니다. 

그런데 일반적으로 하둡 프로젝트에서 한번만 맵리듀스를 사용하는 경우는 거의 없습니다. 

대부분 맵 리듀스를 반복적으로 사용하게 됩니다. 


여기에 맵리듀스에서 기본적으로 사용하는 타입인 Text, IntWritable, LongWritable과 같은 것 이외에 객체를 사용한다든지. 

Key 항목이 아닌 Value에 속하는 항목으로 정렬을 하고 싶다든지, 

하는 경우에 많은 개발자들이 어려움을 느끼고 있습니다. 


물론 위와 같은 문제들에 대한 해결책은 맵리듀스에 존재합니다. 

그러나 마치 어셈블리어로 모두다 가능하지만 고급언어로 씌워서 개발자가 좀 더 편하게 개발할 수 있는 환경을 만드는 것처럼 

하둡에서도 맵리듀스로 변환해 줄 수 있는 스크립트 언어들이 존재합니다. 


제가 굳이 고급 언어라고 하지 않고 스크립트 언어라고 하는 이유는 

개인적으로는 아직까지 맵리듀스가 더 나을 수 있다고 보기 때문입니다. 

물론 시간이 흘러 스크립트 언어들의 성능 개선이 이루어지겠지만 맵리듀스로 변환해야 하는 오버헤드는 존재하겠죠.. 


Google Sawzall

이런 스크립트 언어를 맨 처음 만든 것은 역시 Google 이었습니다. 

구글은 GFS와 맵리듀스에서 사용할 수 있는 절차형 프로그래밍 언어를 개발했고 Sawzall 이라는 이름으로 사용하고 있다고 합니다. 


이런 Sawzall을 모델로 Hadoop과 관련한 프로젝트들이 만들어집니다. 

바로 Hive와 Pig 입니다. 



Hive

먼저 Hive부터 살펴보도록 하죠. 

Hive는 HiveQL이라고 하는 SQL과 유사한 쿼리를 사용합니다. 

HiveQL로 정의한 내용을 Hive가 MapReduce Job으로 변환해서 실행한다고 합니다. 


정확하게 설명하면, MapReduce 작업이 필요할 때 Hive는 Java MapReduce 프로그램을 생성하는 것은 아니라고 합니다. 

인터프리터 언어처럼 내장된 Generic Mapper와 Reducer 모듈을 사용하고, 

여기에 Job Plan이라는 XML 파일을 적용해 MapReduce Job을 생성한다고 하네요. 

이렇게 MapReduce Job을 생성하면서 비로소 Job Tracker와 통신하기 시작한다고 합니다. 


Facebook 주도로 개발했고 국내에서도 Hive를 위주로 사용하는 곳도 있습니다. 


예를 한번 살펴보도록 하죠. 

Q) K1 메타 저장소에서 Key 값이 100보다 큰 것을 Key와 count로 출력

hive> select key, count(1) from kv1 where key > 100 group by key


위와 같은 형태로 구현이 가능하다고 합니다. 

실제 SQL 쿼리를 사용하는 것과 같은 느낌이 듭니다. 


이번에는 Hadoop의 기본 예제로 사용하는 WordCount를 Hive로 구성해 보도록 하겠습니다. 

WordCount에 대한 MapReduce 설명은 http://blog.acronym.co.kr/333#wordcount 을 참고하시기 바랍니다. 

CREATE TABLE docs (line STRING);
LOAD DATA INPATH 'docs' OVERWRITE INTO TABLE docs;

CREATE TABLE word_counts AS
SELECT word, count(1) AS count
FROM
   (SELECT explode(split(line,'\s')) AS word FROM docs) w
GROUP BY word
ORDER BY word;



구성도를 살펴보면 Hive에 Metastore가 존재합니다. 

이 부분에 DB 스키마와 같이 저장하는 것 같고 실제 데이터는 하둡의 HDFS에 분산되어 저장되는 구조인 듯 합니다. 

Metastore는 별도의 Relation Database로서 일반적으로 MySQL 인스턴스를 사용한다고 합니다. 

즉, Hive는 주로 MySQL을 사용하여 테이블 스키마와 시스템 메타데이터를 유지하고 있다고 보면 됩니다. 


JDBC, ODBC 드라이버가 존재하는 것으로 봐서 기존 DB와도 연동해서 사용할 수 있는 것 같네요. 

뿐만 아니라, CLI (Command Line Interface), HWI (Hive Web Interface), 그리고 Thrift 서버 프로그래밍을 제공합니다. 


최근에는 다양한 GUI 툴도 제공하고 있는데요. 

Karmasphere(http://karmasphere.com), Cloudera의 Hue (https://github.com/cloudera/hue), 

그리고 Hive-as-a-service를 제공하는 Qubole(http://qubole.com)를 Hive GUI로 활용할 수 있습니다.


Pig

Pig와 관련해서는 http://blog.acronym.co.kr/372 에서 간단하게 정리하기는 했는데요. 

MapReduce의 비직관적이고 반복되는 코딩을 줄이기 위해 간결한 문법으로 새로 만든 스크립트 언어입니다. 

정확하게 설명하면, Pig는 Query Language가 아닌 Data Flow를 처리하는 Laguage라 할 수 있습니다. 


사용자 정의 함수로 확장이 가능하지만 컴파일 과정이 필요하므로 MapReduce에 비해 성능이 떨어진다고 하네요. 

야후(Yahoo)에서는 하둡 작업의 30%를 Pig를 사용하고 있고, 트위터도 사용한다고 들었던 것 같습니다. 

또한 Pig는 외부 데이터를 하둡 클러스터로 가져오고 적절한 형식으로 변환하기 위한 ETL(Extract, Transform, and Load) 프로세스의 일부로도 종종 사용된다고 합니다. 


Pig에 대한 예제를 Hadoop 완벽 가이드에 나오는 내용을 기반으로 살펴보죠. 


Q) 날씨 데이터에서 연중 가장 높은 기온을 계산하는 프로그램

1: grunt> records = LOAD ‘input/sample.txt’
2: >> AS(year: chararray, temperature:int, quality:int);
3: grunt> filtered_records = FILTER records BY temperature != 9999
4: >> AND quality == 1
5:
6: grunt> grouped_records = Group filtered_records BY year;
7: grunt> max_temp = FOREACH grouped_records GENERATE group,
8: >> MAX(filtered_records.temperature);
9:
10: grunt> DUMP max_temp;
11: (1949, 111)
12: (1950, 22)


1~2번째 줄을 보면 HDFS에서 input/ 폴더의 sample.txt를 가져와서 year, temperature, quality를 중심으로 분류합니다. 

그리고 3~4번째 줄에 temperature와 quality가 적절한 값들만 필터링해서 filtered_records에 저장합니다. 

6번째 줄에서 연도별을 기준으로 그룹화해서 grouped_records에 저장합니다. 

그리고 7~8번째 줄에서 각 그룹별로 최고 기온을 체크해서 max_temp에 저장하고 

마지막에 max_temp를 출력하면 결과가 위와 같이 나옵니다. 


실제 관련 책을 보면 위 내용을 맵리듀스로 작성하는 내용이 나옵니다. 

비교해보면 정말 간단하기는 합니다. 


In Pig, you write a series of declarative statements that define relations from other relations, 

where each new relation performs some new data transformation.

Pig looks at these declarations and then builds up a sequence of MapReduce jobs 

to perform the transformations until the final results are computed the way that you want.


마치면서

이상으로 Hive와 Pig에 대해서 간략하게 정리해 봤습니다. 

분명 Hive나 Pig는 발전하고 있고 프로그래밍하기에 보다 편리한 것이 사실입니다. 

하지만 개인적으로는 반드시 하둡을 사용하려면 MapReduce로 한번쯤 직접 해 보시기를 권장하고 싶습니다. 


MapReduce의 처리 흐름을 이해하고 난 뒤 Hive나 Pig를 사용해도 늦지 않을 것이라는 생각이거든요. 

어차피 내부적으로 MapReduce로 변환해 실행한다면 MapReduce를 이해하고 있어야 나중에 응용도 보다 자유롭게 하지 않을까 합니다. 


-- 2012년 11월 2일 작성한 글을 최신 내용으로 업데이트 했습니다. 






Trackback 0 And Comment 0

하둡(hadoop) 맵리듀스 프로그래밍을 위한 이클립스 설정 및 맵리듀스 개발 #2

|



하둡과 관련되어 작성한 글 목록을 먼저 보여드립니다. 참고하시기 바랍니다. 

2012/02/29 - [리뷰/블로그] - BigData 처리를 위한 맵리듀스(MapReduce)에 대하여~

2012/05/18 - [프로그래밍/Java] - 하둡(Hadoop) 설치부터 테스트까지 정리~

2012/05/22 - [프로그래밍/Java] - 하둡 맵리듀스 프로그래밍을 위한 이클립스 플러그인 설정 #1


지난 시간에 Mac에 이클립스 플러그인을 설치하는 과정을 살펴봤는데요. 

마지막에 설명한 것처럼 플러그인의 장점을 충분히 살리지 못하고 있으며 약간의 버그들도 존해하기 때문에 큰 의미가 없었습니다. 

그래서 이번에는 일반적인 자바 프로젝트로 개발 환경을 설정하고 word count를 처리하는 예제를 실제로 실행해 보도록 하겠습니다. 


이클립스 하둡 맵리듀스 개발 환경 설정


새 프로젝트 생성

먼저 Hadoop 이라는 이름으로 새로운 프로젝트 생성을 하는데요. 일반적인 자바 프로젝트로 진행하시면 됩니다. 

create java project in eclipse

create java project named hadoop

다음과 같이 프로젝트가 생성된 것을 볼 수 있습니다. 

생성된

Hadoop에서 제공하는 conf/ 파일들이 필요하므로 복사할 수 있도록 conf/라는 폴더도 하나 생성하도록 하죠.. 

프로젝트에서 우클릭한 후, New > Folder > conf 라고 만드시면 다음과 같이 나타납니다. 

conf 폴더 생성


개발 환경 설정

이제 하둡 이클립스 플러그인으로 생성한 것과 비슷하게 각종 jar 파일들을 적용하는 환경 설정을 해보도록 하겠습니다. 

프로젝트에서 우클릭 한 후, "Properties"를 실행합니다. 

그리고 좌측에서 "Java Build Path"를 선택하고 우측의 탭 중에서 "Libraries"를 선택하면 다음과 같은 화면이 나타납니다. 

java build path의 Libraries 설정

먼저 "Add External JARs..."를 선택해서 Hadoop 관련된 다음 jar 파일들을 추가해 주시면 됩니다. 

  • /hadoop-1.0.1/hadoop*.jar
  • /hadoop-1.0.1/lib/*.jar

Add External Jar

그리고 "Add Class Folder..."를 클릭해서 위에서 생성한 conf/ 폴더를 지정합니다. 

add class folder

마지막으로 하둡이 설치된 곳에서 conf/ 하위의 파일들을 현재 프로젝트의 conf/ 폴더로 복사합니다. 

copy files to conf folder

자.. 개발 환경 설정이 모두 종료되었습니다. 

이제부터는 맵리듀스 프로그래밍을 시작해 보도록 하죠. 

예제는 hadoop 설치 소스에 포함된 wordcount를 가지고 실제 만들어서 진행해 보도록 하겠습니다. 


wordcount 맵리듀스 테스트

하둡 설치 폴더에 보면 /hadoop-1.0.1/docs/index.html 파일을 실행해 보시기 바랍니다. 

뭐든지 제작사가 직접 만든 Document가 가장 신뢰성있는 정보를 제공하는 것 같습니다. 

첫 화면은 다음과 같습니다. 

hadoop documents

여러가지가 있는데요.. 필요한 분들은 추후 천천히 살펴보시기 바랍니다. 

여기에서는 맵리듀스에 관심이 있으므로 MapReduce Tutorial을 따라서 진행해 보도록 하겠습니다. 

MapReduce tutorial


맵리듀스 소스 코딩

맵리듀스 튜토리얼을 살펴보면 중간에 Example: WordCount v1.0이라는 부분이 있습니다. 

이 예제를 가지고 위에서 세팅한 이클립스로 코딩을 해보도록 하죠.. ^^

위에서 설정한 hadoop 프로젝트에서 src/ 하위에 새로운 패키지와 자바 파일을 만들도록 하겠습니다. 

패키지명: kr.acronym.wordcount

클래스명: WordCount

create java package

create java class

그리고 나서 WordCount.java에 다음과 같이 소스 코드를 넣습니다. 

이 소스는 hadoop의 mapreduce tutorial에서 가져온 내용입니다. ^^

이클립스에서 보면 에러 표시가 안 나타나는 것을 볼 수 있습니다. 

혹시 에러가 나는 분들은 앞부분의 개발 환경 설정이 잘못된 경우이니 처음부터 다시 따라해 보시기 바랍니다. 


컴파일 및 jar 파일 생성

튜토리얼에는 콘솔 명령어로 컴파일하고 jar 파일을 생성하는 것을 설명하고 있습니다. 

이클립스와 같은 툴을 사용하는 이유는 이런 작업을 좀 편하게 하기 위함이죠.. 

이클립스를 통해서 컴파일하고 jar 생성하는 것은 잘 알겠지만 여기에서 한번 더 진행해 보도록 하겠습니다. 

먼저 프로젝트에서 우클릭한 후, Export..를 선택하면 나오는 화면에서 JAR file을 선택합니다. 

create Jar file

이어지는 화면에서 조금 전 코딩한 WordCount 클래스를 포함한 패키지를 선택합니다. 

그리고 필요한 경우 "Select the export destination"에서 저장할 경로를 지정합니다. 

Jar file specification

이제 "Finish" 버튼을 클릭하면 wordcount.jar 파일이 만들어집니다. 

("Next>"를 클릭해서 각각 세부 정보를 설정할 수도 있습니다. 이건 각자 살펴보세요 ^^)


WordCount 실행으로 결과 확인

지금부터 실행하는 것은 콘솔 명령어로 하도록 하겠습니다. 

추후 기회가 되면 ANT 빌드로 만들어서 이클립스에서 한번에 처리할 수 있도록 구성할 수도 있겠죠.. 


지난번 하둡(Hadoop) 설치부터 테스트까지 정리~ 예제를 따라 했다고 생각하고 시작하도록 하겠습니다. 

(위 예제를 모두 따라 했다면 HDFS의 input/ 폴더와 output/폴더가 이미 생성되어 있을 겁니다.)

먼저 조금전 jar 파일이 생성된 폴더로 이동을 합니다. 

# cd /Users/minikim/Dev/jar/

그리고 이전에 생성된 HDFS의 input/과 output/ 폴더의 내용을 모두 삭제하도록 하겠습니다. 

# hadoop dfs -rm input/CHANGES.txt

# hadoop dfs -rmr output/

첫번째 라인은 앞선 예제에서 실행한 CHANGES.txt 파일만 지운 것이구요. 

두번째 라인은 output/ 폴더 전체를 삭제한 것입니다. 


맵리듀스를 한번 실행하고 난 뒤 다시 실행하면 "org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory  .... already exists" 라는 에러 메시지가 나타납니다. 

이 경우, output 폴더의 내용을 지우거나 결과를 저장하는 위치를 변경해야 한다고 하네요. 


이제 단어 숫자를 셀 파일들을 한번씩 만들어 보겠습니다. 

# vi file01

Hello World Bye World

# vi file02

Hello Hadoop Goodbye Hadoop

텍스트 파일 만드는 것이야 어렵지 않으니 쉽게 따라 하실 수 있을 것 같네요.. ^^

이렇게 생성된 파일들을 HDFS의 input/ 폴더에 복사하도록 할께요. 

이어서 잘 복사가 되었는지도 확인해 봤습니다.

# hadoop dfs -put file01 input/

# hadoop dfs -put file02 input/

# hadoop dfs -ls input/

Warning: $HADOOP_HOME is deprecated.

Found 2 items

-rw-r--r--   3 minikim supergroup         22 2012-05-23 18:08 /user/minikim/input/file01

-rw-r--r--   3 minikim supergroup         28 2012-05-23 18:13 /user/minikim/input/file02

이제 앞에서 만든 wordcount를 실행해서 실제 결과가 나오는지 확인해 보도록 하죠.. 

# hadoop jar wordcount.jar kr.acronym.wordcount.WordCount input/ output/

mapreduce result

제대로 실행이 됩니다. 그럼 결과를 확인해 보도록 하죠^^

output/ 폴더를 보면 part-00000 파일이 생성된 것을 볼 수 있구요. 

이 파일의 내용을 보면 단어 갯수 체크가 되어 있습니다. 

# hadoop dfs -ls output

# hadoop dfs -cat output/part-00000

이제 이클립스에서 맵리듀스 프로그래밍을 하고 결과가 제대로 나오는 것 까지 확인을 했네요.. 

이번 글은 정말 길었습니다. 하나하나 자세히 설명하다보니~

저도 처음 해보면서 너무 정신없었던 기억에 이렇게 정리를 한번 해봅니다. 

추후 기회가 되면 jar 생성 이후 과정을 자동화 하는 것도 한번 처리해 보도록 하죠.. 

그럼.. 좋은 하루 되세요~





Trackback 0 And Comment 3

하둡 맵리듀스 프로그래밍을 위한 이클립스 플러그인 설정 #1

|



요즘 하둡(Hadoop)을 계속해서 테스트해보고 있습니다. 

지난번에 설치는 2012/05/18 - [프로그래밍/Java] - 하둡(Hadoop) 설치부터 테스트까지 정리~ 에서 정리했었는데요. 

이번에는 맵리듀스 프로그래밍을 위한 이클립스 설정을 살펴보도록 하겠습니다. 

참고로 이번부터는 맥에서 하둡을 설치하고 테스트를 진행했네요. 


Apache Ant / Ivy 다운로드 및 설치

하둡 내부의 소스 폴더를 보면 ant build를 많이 사용하고 있습니다. 

자바 프로젝트를 하면서 Ant는 기본적으로 설치되어 있을텐데요. 

제 Mac에서도 /usr/share/java/ant-1.8.2/에 설치되어 있네요. 


Ant가 설치되어 있으면 이어서 Apache Ivy를 설치해야 합니다. 

하둡에서도 Ivy를 사용하고 있는데요. Apache ivy는 자바 프로젝트의 의존성을 관리해 주는 도구입니다. 

즉, Ant 빌드에 세팅된 정보를 이용하여 각 라이브러리를 참조한 뒤 의존성 검사를 수행하고 검사결과도 HTML 형태로 보여주기도 합니다. 

다운로드는 http://ant.apache.org/ivy/download.cgi 에서 하면 됩니다. 

apache-ivy-2.3.0-rc1-bin.tar.gz 파일을 받아서 압축을 풀면 ivy-2.3.0-rc1.jar 파일을 찾을 수 있습니다.

이 파일을 Ant 가 설치된 폴더의 lib/에 복사하시면 됩니다. (/usr/share/java/ant-1.8.2/lib)


이클립스 플러그인 Ant 빌드

이클립스에 세팅하기 위해서 먼저 테스트한 것은 이클립스 플러그인 입니다. 

하둡을 다운로드하고 소스들을 살펴보면 eclipse-plugin이라는 폴더가 있습니다. 

(정확한 위치는 /hadoop-1.0.1/src/contrib/eclipse-plugin 이네요.)

contrib인 걸로 봐서 Third Party에서 개발해서 제공한 것 같은데요. 


Ant 빌드를 세팅했으므로 아무 생각없이 먼저 Build를 실행해 봤습니다. 

아래 그림과 같이 뭔가 동작하는 것 같기는 하지만, compile과 jar에서 아무 내용이 없는 것을 확인할 수 있습니다. 


build.xml 파일을 열어보니 compile과 jar에서 사용하는 eclipse.home이나 version과 같은 property가 설정이 안되어 있었습니다. 

그래서 해당 property를 설정하고 다시 Ant 빌드를 수행했습니다. 

  <property name="eclipse.home" value="/Applications/eclipse"/>

  <property name="version" value="1.0.1"/>

결과는 역시 Build Fail.... 100개의 Error가 발생했네요~ 


오류메시지와 build.xml 파일을 살펴보니 자바 컴파일 중에 난 에러인데요.. 

hadoop 관련된 jar 파일들이 포함되지 않아서 발생한 것 같네요. 

그래서 hadoop-core와 hadoop-lib에 대한 classpath를 다음과 같이 설정해 봤습니다. 

(먼저 path를 정의하고, classpath에 참조하는 형태로 구성했네요.)

  <path id="hadoop-core">

<fileset dir="${hadoop.root}/">

<include name="hadoop*.jar"/>

</fileset>

  </path>


  <path id="hadoop-lib">

<fileset dir="${hadoop.root}/lib/">

<include name="*.jar"/>

</fileset>

  </path>


....


  <path id="classpath">

    <pathelement location="${build.classes}"/>

    <pathelement location="${hadoop.root}/build/classes"/>

    <path refid="hadoop-core"/>

    <path refid="hadoop-lib"/>

    <path refid="eclipse-sdk-jars"/>

  </path>

다시 Ant 빌드 해보니 아래와 같은 오류가 나오네요.. 휴~ 정말 직접 만든게 아니라 끝이 없네요.. ㅋㅋ


오류 메시지를 잘 살펴보니 build에 hadoop-core-1.0.1.jar 파일이 없다는 것 같습니다. 

그래서 /hadoop-1.0.1 하위에 있는 hadoop-core-1.0.1.jar 파일을 build 폴더 밑으로 복사했습니다. 

마찬가지로 Ant 빌드를 해보면 commons-cli-1.2.jar 파일 관련 오류가 나오므로 마찬가지로 지정한 위치로 복사했네요. 

(위치가 조금 다릅니다. 다음 내용 참고하세요)

# cp hadoop-core-1.0.1.jar build/

# cp lib/commons-cli-1.2.jar build/ivy/lib/Hadoop/common/

드디어 eclipse plugin에 대한 Ant Build를 성공했습니다. ^^ 

/hadoop-1.0.1/build/contrib/eclipse-plugin 폴더에 보면 hadoop-eclipse-plugin-1.0.1.jar 파일이 생성된 것을 볼 수 있습니다. 



이클립스 플러그인 적용

생성된 파일을 이클립스의 plugin 폴더에 복사하고 이클립스를 재시작하면 해당 플러그인이 적용됩니다.

Perspective를 보면 다음 그림과 같이 코끼리 모양의 MapReduce를 추가할 수 있습니다. 


좌측 상단에 보면 DFS Locations라고 나와 있습니다. 
하둡의 파일 시스템인 HDFS를 관리하는 것 같습니다. 
그러나 Mac에 설치된 이클립스에서는 로그인이 안되는 문제가 있네요. 
아마도 SSH 관련 설정 때문인 듯 한데요.. 요건 어쩔 수 없는 것 같습니다. 


다음은 localhost에 설치된 하둡의 DFS에 연결하는 부분입니다.
Map/Reduce Master는 mapred-site.xml에서 설정한 mapred.job.tracker의 값인 듯 하구요. 
DFS Master는 core-site.xml에 설정한 fs.default.name의 값인 것 같네요. 

어쨌든 연동이 되지 않는 문제가 있습니다. 

곰곰히 생각해보니 DFS와 같은 하둡에 연동이 안된다면 굳이 플러그인을 사용하는 것이 의미가 있을까 하는 의문이 드네요. 헐~

윈도우에서는 동작할 것 같기는 한데요.. cygwin과 같은 것을 설치해야 하니 부담이 있을 듯 하구요.. 

localhost가 아닌 원격으로 세팅하면 될 것 같기도 한데.. 거기까지는 다음에 다시 한번 테스트 해보도록 하죠. 


일단 이어서 MapReduce 프로젝트로 wordcount를 하나 생성해 봤습니다. 



그런데 생성해보니 버그인지 프로젝트가 두개가 생겼습니다. 하나를 지우면 같이 사라지는 것으로 봐서 버그인 듯 하네요.. 

더욱 당황스러운 것은 기본적인 jar 파일을 포함한 것 이외에 다른 템플릿이 전혀 없다는 것입니다. 

헉! 왜 이걸 빌드하고 적용했지? 하는 생각이 밀려오네요.. ㅠㅠ


정리

현재까지 살펴본 바에 따르면 일단 다음과 같이 정리할 수 있습니다. 

  1. Mac의 이클립스에서는 HDFS를 연결해도 SSH로 접속이 되지 않습니다. 
  2. MapReduce 프로젝트를 생성하니 프로젝트가 두개씩 보여지고 jar 파일 import외에는 특별한 템플릿이 없습니다.

위 내용을 토대로 생각해보면 

이클립스 플러그인을 적용해서 맵리듀스 프로그래밍을 할 필요가 현재까지는 없다는 것입니다. 

그렇다면 차라리 이클립스에 기본적인 자바 프로젝트로 생성하고 jar만 잘 import 해줘서 

맵리듀스 프로그래밍에 대한 컴파일과 결과 파일인 jar 생성만 잘 해주면 된다는 것이죠. 

다음에는 이 방식으로 이클립스 맵리듀스 개발 환경 세팅을 다시 정리해 보려고 합니다. 






Trackback 0 And Comment 0
prev | 1 | next