출처 : http://www.ibm.com/developerworks/kr/library/j-javadev2-15/
Google이 2001년에 이미지 검색 기능을 실행했을 때, 2억 5천만 개의 인덱스된 이미지를 보유했다. 십 년이 지나지 않아, 이 검색 거인은 100억 개 이상의 이미지를 인덱스했다. 분당 35시간의 컨텐츠가 YouTube로 업로드된다. Twitter는 평균적으로 매일 5천 5백만 건의 트윗을 처리한다고 주장한다. 올해 초에 그 검색 기능은 매일 6억 개의 쿼리를 로깅했다. 대용량 데이터를 논의할 때 대용량이란 바로 그 정도이다.
이러한 엄청난 규모의 데이터는 대기업, 대학 및 정부 — 엄청나게 비싼 슈퍼컴퓨터를 구입할 수 있으며 이를 계속 실행할 직원을 가용할 수 있는 단체 —에 국한되었다. 오늘날 스토리지 비용의 절감과 프로세싱 성능의 상용화를 통해 중소기업 및 일부 개인들도 동일한 데이터를 저장하고 마이닝하기 시작하여, 애플리케이션 혁신의 흐름을 발전시킨다.
대용량 데이터 혁명이 가능한 기술 중 하나는 MapReduce이다. 이는 엄청난 규모의 분산 데이터 세트를 처리하기 위해 Google이 개발한 프로그래밍 모델 겸 구현 방식이다. 이 기사에서 필자는 Apache의 오픈 소스 MapReduce 구현 방식인 Hadoop을 소개한다. 이는 클라우드 컴퓨팅의 킬러 앱(killer app)이라고도 한다.
Apache의 Hadoop 프레임워크는 본질적으로 대용량 데이터 세트를 분석하기 위한 메커니즘이며, 이는 반드시 데이터 저장소에 수용하지 않아도 된다. Hadoop은 MapReduce의 거대한 데이터 분석 엔진을 요약하여 개발자들이 액세스하기에 더 쉽게 만든다. Hadoop은 무수한 노드로 확장하여 데이터 정렬과 관련된 활동 및 조정을 모두 처리할 수 있다.
Hadoop은 수많은 기능과 구성을 통해 놀랍도록 유용하고 강력한 프레임워크가 된다. Yahoo!와 무수한 다른 조직들은 산더미 같은 비트와 바이트들을 분석하기 위해 이를 효율적인 메커니즘이라고 인식했다. 또한 Hadoop은 단일 노드에서 작업하기에 매우 간편하다. 즉, 분석할 데이터가 어느 정도 있고, 제네릭을 비롯한 Java 코드에 익숙하기만 하면 된다. Hadoop은 또한 Ruby, Python 및 C++로 작업한다.
대용량 데이터 세트를 처리하기 위한 개념적인 프레임워크로서 MapReduce는 다수의 컴퓨터를 사용하여 분산된 문제 해결을 위해 고도로 최적화되었다. 프레임워크는 이름이 암시하는 대로 두 가지 함수로 구성된다. map
함수는 대용량 데이터 입력을 취하여 더 잘게 나누도록 설계되었으며, 그러면 이를 통해 어떠한 작업을 할 수 있는 다른 프로세스로 전달한다. reduce
함수는 map
으로 수집되는 개별 응답을 요약하고 최종 출력으로 이를 렌더링한다.
Hadoop에서 Hadoop의 자체적인 기본 클래스를 확장하여 map
과 reduce
구현을 정의한다. 구현은 입력 및 출력 형식과 함께 이를 지정하는 구성으로 함께 묶인다. Hadoop은 구조화된 데이터가 들어있는 대용량 파일을 처리하기 위한 훌륭한 세트이다. Hadoop의 특히 편리한 측면 하나는 입력 파일의 원시 구문 분석을 처리하기 때문에, 사용자는 한 번에 한 행씩 다룰 수 있다. 따라서 map
함수를 정의하는 것은 실제로 텍스트의 수신되는 행에서부터 취하려는 것을 판별하는 문제에 불과하다.
미국 정부는 일반 시민이 크게 관심을 가지는 엄청난 양의 데이터를 제작한다. 다양한 정부 기관들은 미국 경제 상태 및 변화하는 사회적 인구 통계와 관련된 데이터를 자유롭게 분배한다. 미국 지질 조사소(USGS)는 국제적인 지진 데이터를 발표한다.
여러 소규모 지진들이 전 세계 곳곳에서 매일 발생한다. 이들 중 다수는 지각 내 깊은 곳에서 발생하여 아무도 인식하지 못하지만, 그럼에도 불구하고 청취 스테이션은 이를 기록한다. USGS는 주간 CSV(또는 콤마로 분리된 값) 파일 형태로 지진 데이터를 발표한다.
평균적인 주간 파일은 엄청나게 크지는 않다 — 겨우 100KB 정도이다. 하지만 이는 Hadoop을 학습하기 위한 기초로 쓰일 것이다. 그렇다고 하더라도 Hadoop이 훨씬 더 큰 규모의 데이터 세트를 처리할 수 있다는 점을 잊지 말자.
최근에 USGS 웹 사이트에서 다운로드한 CSV 파일은 다음 리스트 1과 같이 약 920개의 행으로 되어있다.
리스트 1. USGS 지진 데이터 파일의 행 개수
$> wc -l eqs7day-M1.txt 920 eqs7day-M1.txt |
CVS 파일의 컨텐츠는 다음 리스트 2(즉, 처음 두 개의 행)에서 보는 것과 비슷하다.
리스트 2. CVS 파일의 처음 두 개의 행
$> head -n 2 eqs7day-M1.txt Src,Eqid,Version,Datetime,Lat,Lon,Magnitude,Depth,NST,Region ci,14896484,2,"Sunday, December 12, 2010 23:23:20 UTC",33.3040,-116.4130,1.0,11.70,22, "Southern California" |
특히 총 행의 합이 920개라는 점을 고려할 때에, 필자는 이를 Information Rich 파일이라고 할 것이다. 하지만 필자는 이 파일로 보고되는 그 주의 각 날짜에 발생하는 지진의 수만 알고자 한다. 그 다음에 이러한 7일에 대부분의 지진이 나타나는 일반적인 영역이 어디인지 알고자 한다.
필자의 첫 번째 생각은 일일 지진 수를 검색하기 위해 간단한 grep
명령을 사용할 수 있었다는 점이다. 파일을 살펴보면 데이터가 12월 12일에 시작하는 것으로 표시된다. 따라서 다음 리스트 3의 결과로 그 문자열의 grep -c
를 수행한다.
리스트 3. 12월 12일에 지진이 얼마나 많이 발생하는가?
$> grep -c 'December 12' eqs7day-M1.txt 98 |
이제 12월 12일에 98개의 항목 또는 98개의 기록된 지진이 있었음을 알게 되었다. 행 아래로 이동하여 12월 11일, 10일 등에 grep
을 수행할 수도 있을 것이다. 하지만, 그것은 필자가 생각하기에는 지루하다. 더욱 나쁜 것은 이를 이끌어 내기 위해 파일에 어느 날짜가 있는지 알아야 한다는 것이다. 필자는 그 내용에 실제로 신경을 쓰지 않으며, 어떠한 경우에는 그러한 정보에 액세스 권한이 없을 수 있다. 실제로 필자는 어느 7일 범위에서나 주어진 각 날짜의 숫자만 알고자 하고, Hadoop을 통해 그러한 정보를 간편하게 얻을 수 있다.
Hadoop은 필자의 첫 번째와 두 번째 질문에 응답하는 정보의 몇 가지 부분만 필요로 한다. 다시 말해서, 처리할 입력이 어느 것이며, map
과 reduce
를 어떻게 다루느냐이다. 또한 모두 함께 묶는 작업도 제공해야 할 것이다. 하지만, 그 코드에 작업을 시작하기 전에 전부 필자의 CSV 데이터 순서로 되어 있는지 확인하는 데 수분이 걸릴 것이다.
지진 CSV 파일의 첫 행인 헤더를 제외하고 각 행은 콤마로 분리된 데이터 값의 시리즈이다. 필자는 세 가지 데이터 부분인 각 지진의 날짜, 위치 및 규모에 주로 관심이 있다. 이러한 데이터를 확보하기 위해 opencsv
라는 실용적인 오픈 소스 라이브러리를 사용할 것이며, 이는 CSV 파일을 구문 분석하는 데 유용하다.
테스트를 우선 시행하는 사람이 되기 위해, 목록 4와 같이 CSV 파일에서 확보한 샘플 행에서 원하는 정보를 확보할 수 있는지 확인하는 빠른 JUnit 테스트를 작성하여 시작할 것이다.
리스트 4. CSV 행 구문 분석하기
public class CSVProcessingTest { private final String LINE = "ci,14897012,2,\"Monday, December 13, 2010 " + "14:10:32 UTC\",33.0290,-115." + "5388,1.9,15.70,41,\"Southern California\""; @Test public void testReadingOneLine() throws Exception { String[] lines = new CSVParser().parseLine(LINE); assertEquals("should be Monday, December 13, 2010 14:10:32 UTC", "Monday, December 13, 2010 14:10:32 UTC", lines[3]); assertEquals("should be Southern California", "Southern California", lines[9]); assertEquals("should be 1.9", "1.9", lines[6]); } } |
리스트 4에서 확인 가능한 대로, opencsv
는 콤마로 분리된 값으로 매우 간단하게 작업하게 해준다. 구문 분석기는 간단하게 String
의 배열을 리턴하므로, 위치 상의 값을 확보할 수 있다(Java 언어에서 배열 및 콜렉션 액세스가 제로 기반인 것을 기억하자).
MapReduce로 작업할 때에 map
함수의 작업은 일부 키에 추가로 작업하기 위해 일부 값을 선택하는 것이다. 다시 말해서, map
은 주로 두 가지 요소로 작업하고 리턴한다. 이는 키와 값이다. 이전의 요구사항으로 돌아가서 필자는 우선 매일 지진이 얼마나 발생하는지 알아내고자 한다. 따라서, 지진 파일을 분석할 때에 두 가지 값을 도출할 것이다. 즉, 키는 날짜가 될 것이고, 값은 카운터가 될 것이다. 그러면 reduce
함수가 카운터를 합하여(이는 1의 값으로 정수임), 대상 지진 파일에서 날짜당 발생하는 횟수를 제공할 것이다.
24시간 기간에 관심이 있기 때문에, 각 파일에서 날짜의 시간 부분을 삭제해야 할 것이다. 다음 리스트 5에서 수신되는 파일에서 특정 날짜 형태를 더 일반적인 24시간 기간 날짜로 어떻게 전환하는지 유효성 검증하는 빠른 테스트를 작성한다.
리스트 5. 날짜 형식 변환
@Test public void testParsingDate() throws Exception { String datest = "Monday, December 13, 2010 14:10:32 UTC"; SimpleDateFormat formatter = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy HH:mm:ss Z"); Date dt = formatter.parse(datest); formatter.applyPattern("dd-MM-yyyy"); String dtstr = formatter.format(dt); assertEquals("should be 13-12-2010", "13-12-2010", dtstr); } |
리스트 5에서 SimpleDateFormat
Java 오브젝트를 사용하여 Monday, December 13, 2010 14:10:32 UTC의 CSV 파일 형식에서 날짜 String
을 더 일반적인 13-12-2010으로 형식화했다.
이제 CSV 파일과 데이터 형식을 어떻게 처리할 것인지에 대한 작업을 했으니, Hadoop에서 map
과 reduce
함수를 구현하여 시작할 차례가 되었다. 이 프로세스는 Hadoop이 명시 유형 안전을 선호하기 때문에, Java 일반을 이해하는 것이 필요하다.
Hadoop으로 map 구현을 정의할 때에 Hadoop의 Mapper
클래스를 간단하게 확장한다. 그러면 발신되는 키와 값 모두에 대한 명시 유형을 지정하기 위해 일반을 사용할 수 있다. 또한 유형 절은 수신되는 키와 값을 설명하며, 이는 파일 읽기의 경우에 이는 각각 바이트 개수와 텍스트의 행이다.
EarthQuakesPerDateMapper
클래스는 Hadoop의 Mapper
오브젝트를 확장한다. 이는 명시적으로 출력 키를 Text
오브젝트로 설명하고 그 값을 IntWritable
로 설명하며, 이는 본질적으로 정수인 Hadoop 특화된 클래스이다. 또한 클래스 절에서 처음 두 개의 유형은 LongWritable
과 Text
이며, 이는 각각 바이트 개수와 텍스트의 행임을 참고하자.
클래스 정의에서 유형 절로 인해 map
메소드로 수신되는 매개변수 유형은 context.write
절 내에서 이 메소드의 출력과 함께 설정된다. 다른 것을 지정하려고 시도하면, 컴파일러 문제가 발생하거나 Hadoop에서 유형 불일치를 설명하는 메시지가 표시되며 오류가 나타날 것이다.
리스트 6. 맵핑 구현
public class EarthQuakesPerDateMapper extends Mapper<LongWritable, Text, Text, IntWritable> { @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { if (key.get() > 0) { try { CSVParser parser = new CSVParser(); String[] lines = parser.parseLine(value.toString()); SimpleDateFormat formatter = new SimpleDateFormat("EEEEE, MMMMM dd, yyyy HH:mm:ss Z"); Date dt = formatter.parse(lines[3]); formatter.applyPattern("dd-MM-yyyy"); String dtstr = formatter.format(dt); context.write(new Text(dtstr), new IntWritable(1)); } catch (ParseException e) {} } } } |
리스트 6에서 map
구현은 간단하다. 즉, Hadoop은 기본적으로 입력 파일에서 발견하는 텍스트의 각 행에 대해 이 클래스를 호출한다. CSV의 헤더를 처리하려는 시도를 방지하기 위해 먼저, 바이트 개수(key
오브젝트)가 0이 아닌지 확인한다. 그 다음에, 목록 4와 5에서 이미 확인한 것을 수행한다. 즉, 수신되는 날짜를 취하여 변환한 다음에 이를 발신 키로 설정한다. 또한 하나의 개수인 1을 제공한다. 다시 말해서, 각 날짜에 대해 카운터를 코드했으며 reduce
구현이 호출될 때에, 키와 값의 콜렉션을 받을 것이다. 이 경우에 키는 리스트 7과 같이 날짜와 그 값이 될 것이다.
리스트 7. map 출력과 reduce 입력의 논리적 보기
"13-12-2010":[1,1,1,1,1,1,1,1] "14-12-2010":[1,1,1,1,1,1] "15-12-2010":[1,1,1,1,1,1,1,1,1] |
context.write(new Text(dtstr), new IntWritable(1))
(리스트 6에 있음) 행이 리스트 7과 같이 논리적 콜렉션을 빌드하였음을 참고하자. 아마 이미 확인한 대로, context
는 다양한 정보 부분을 보유하는 Hadoop 데이터 구조이다. 이 context
는 reduce
구현으로 전달되며, 이는 이러한 1 값들을 취하고 이를 합할 것이다. 결과적으로, reduce
구현은 논리적으로 다음 리스트 8에서와 같은 데이터 구조를 작성한다.
리스트 8. reduce 출력의 보기
"13-12-2010":8 "14-12-2010":6 "15-12-2010":9 |
reduce
구현이 리스트 9에 표시된다. Hadoop의 Mapper
인 Reducer
는 매개변수화되었다. 즉, 처음 두 개의 매개변수는 수신되는 키 유형(Text
)과 값 유형(IntWritable
)이고, 나중 두 개의 매개변수는 출력 유형인 키와 값이며, 이 경우에 이는 동일하다.
리스트 9. reduce 구현
public class EarthQuakesPerDateReducer extends Reducer<Text, IntWritable, Text, IntWritable> { @Override protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int count = 0; for (IntWritable value : values) { count++; } context.write(key, new IntWritable(count)); } } |
reduce
구현은 지극히 간단하다. 리스트 7에서 지적한 대로, 수신되는 값은 실제로 값의 콜렉션이며, 이 경우에는 1 값들의 콜렉션을 의미한다. 필자가 수행하는 것은 이를 합한 다음, 날짜와 개수를 표현하는 새로운 키-값 쌍을 작성하는 것이다. 그 다음에 reduce
코드가 기본적으로 리스트 8에서 확인한 행을 산출한다. 논리적 플로우는 다음과 같다.
"13-12-2010":[1,1,1,1,1,1,1,1] -> "13-12-2010":8 |
이 목록의 요약 양식은 물론, map -> reduce
이다.
이제 map
과 reduce
구현을 코드 작성했으니, 남은 일은 Hadoop Job
으로 모두 연결하는 것이다. Job
을 정의하는 것은 간단하다. 즉, 입력과 출력인 map
과 reduce
구현(리스트 6 및 리스트 9에 표시됨) 및 출력 유형을 제공한다. 이 경우에 출력 유형은 reduce
구현에 사용되는 것과 동일하다.
리스트 10. Job은 map과 reduce를 함께 묶는다
public class EarthQuakesPerDayJob { public static void main(String[] args) throws Throwable { Job job = new Job(); job.setJarByClass(EarthQuakesPerDayJob.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); job.setMapperClass(EarthQuakesPerDateMapper.class); job.setReducerClass(EarthQuakesPerDateReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); System.exit(job.waitForCompletion(true) ? 0 : 1); } } |
리스트 10에서 두 개의 매개변수를 취하는 main
메소드로 모두 함께 묶었다. 즉, 이는 지진 CSV 파일인 디렉토리와 결과 보고서가 작성되어야 하는 디렉토리(Hadoop은 이 디렉토리를 작성하는 것을 선호함)이다.
이러한 작은 프레임워크를 실행하려면 이러한 클래스를 jar로 해야 할 것이다. 또한 Hadoop에 opencsv
바이너리를 찾을 수 있는 위치를 알려야 할 것이다. 그 다음에 리스트 11과 같이 명령행을 통해 Hadoop을 실행할 수 있다.
리스트 11. Hadoop 실행하기
$> export HADOOP_CLASSPATH=lib/opencsv-2.2.jar $> hadoop jar target/quake.jar com.b50.hadoop.quake.EarthQuakesPerDayJob ~/temp/mreduce/in/ ~/temp/mreduce/out |
이 코드를 실행하면, Hadoop이 그 작업 수행을 시작하면 화면에 많은 텍스트가 날라다니는 것을 확인할 것이다. 사용 중인 CSV 파일은 Hadoop이 처리하기 위해 빌드한 큰 개와 비교하면 강아지에 불과하다는 점을 유의하자. 처리 성능에 따라 Hadoop은 수 초 내에 이를 완료해야 한다.
완료하면 가상으로 편집기를 통해 출력 파일의 컨텐츠를 볼 수 있다. 또 다른 옵션은 리스트 12에서 수행한 것처럼 hadoop
명령을 직접 사용하는 것이다.
리스트 12. Hadoop의 출력 읽기
$> hadoop dfs -cat part-r-00000 05-12-2010 43 06-12-2010 143 07-12-2010 112 08-12-2010 136 09-12-2010 178 10-12-2010 114 11-12-2010 114 12-12-2010 79 |
독자가 필자와 비슷하다면 리스트 12에서 확인할 첫 번째 내용은 일일 지진의 수 그 자체이다 — 12월 9일에 178만 있다! Hadoop이 필자가 수행하려는 바로 그것을 수행했다는 점도 인식하길 바란다. 필자의 범위 내 모든 날짜에 대해 지진 발생 수를 깔끔하게 표로 만들었다.
다음으로, 지진이 발생하는 위치를 알아내고, 어느 위치가 날짜 범위에서 대부분의 지진을 로그하는지 어떻게든 빠르게 측정하고자 한다. 자, 아마 추측한 대로, Hadoop을 통해 그렇게 간편하게 수행된다. 이 경우에 키는 날짜가 아니라 위치이다. 따라서, 새 Mapper
클래스를 쓴다.
리스트 13. 새 map 구현
public class EarthQuakeLocationMapper extends Mapper<LongWritable, Text, Text, IntWritable> { @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { if (key.get() > 0) { String[] lines = new CSVParser().parseLine(value.toString()); context.write(new Text(lines[9]), new IntWritable(1)); } } } |
날짜를 확보하고 이를 변환하는 것이 아니라, 리스트 13에서 수행한 전부는 위치를 취하는 것이었으며, 이는 CSV 배열에서 최종 위치상의 항목이었다.
위치와 그 숫자의 거대한 목록이 아니라, 결과를 어느 7일 기간에나 10회 이상의 지진이 나타난 위치로 제한하려고 한다.
리스트 14. 어디에서 지진이 더 많이 나타나는가?
public class EarthQuakeLocationReducer extends Reducer<Text, IntWritable, Text, IntWritable> { @Override protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int count = 0; for (IntWritable value : values) { count++; } if (count >= 10) { context.write(key, new IntWritable(count)); } } } |
리스트 14에서 코드는 리스트 9에 있는 것과 매우 유사하다. 하지만 이 경우에 10개 이상의 합으로 출력을 제한했다. 그 다음으로, 새로운 답변을 얻기 위해 map
과 reduce
를 또 다른 Job
구현과 묶고, jar로 만들어 Hadoop을 정상으로 실행할 수 있다.
hadoop dfs
명령을 실행하면 다음과 같이 요청한 새 값을 표시한다.
리스트 15. 위치별 지진
$> hadoop dfs -cat part-r-00000 Andreanof Islands, Aleutian Islands, Alaska 24 Arkansas 40 Baja California, Mexico 101 Central Alaska 74 Central California 68 Greater Los Angeles area, California 16 Island of Hawaii, Hawaii 16 Kenai Peninsula, Alaska 11 Nevada 15 Northern California 114 San Francisco Bay area, California 21 Southern Alaska 97 Southern California 115 Utah 19 western Montana 11 |
리스트 15에서 배울 내용은 무엇인가? 자, 먼저 멕시코에서 알래스카에 이르는 북미의 서부 해안은 불안정한 지역이다. 두 번째로, 아칸소는 명백히 단층선 근처에 위치하고 있으며, 이는 필자가 인식하지 못한 점이다. 마지막으로 독자가 북부 또는 남부 캘리포니아(많은 소프트웨어 개발자들이 거주함)에 산다면 독자 주변의 지반은 대략 매 13분마다 흔들린다.
Hadoop으로 데이터를 분석하는 것은 간편하고 효율적이므로, 데이터 분석을 위해 제공해야 하는 내용조차도 수박 겉핥기식으로 다루지 않았다. Hadoop은 실제로 map
과 reduce
를 실행하는 다양한 노드의 조정을 처리하는 분산된 방식으로 실행하도록 설계되었다. 예제의 목적을 위해 이 기사에서 보잘 것 없는 파일 하나로 하나의 JVM에서 Hadoop을 실행했다.
Hadoop은 보유하기에 그 자체로 탁월한 도구이며, 또한 이와 관련하여 하위 프로젝트에서부터 클라우드 기반 Hadoop 서비스에 이르기까지 전체적이며 성장하는 에코시스템도 있다. Hadoop 에코시스템은 프로젝트 배후에 풍부한 커뮤니티를 시연한다. 커뮤니티에서 파생된 많은 도구들은 전역 비즈니스 활동으로 대용량 데이터 분석의 실행 가능성을 보여준다. Hadoop을 통해 분산 데이터 마이닝과 분석은 Google과 Yahoo!를 포함하지만 이에 국한되지 않은 모든 종류의 소프트웨어 혁신자와 기업가들이 사용할 수 있다.
교육
- Java development 2.0: 이 dW 시리즈에서는 Java 개발 환경을 다시 정의하는 각종 기술을 탐구한다. 최신 주제로는 MongoDB(2010년 9월), CouchDB(2009년 11월) 및 Objectify AppEngine(2010년 11월)이 있다.
- "Hadoop을 이용한 분산 데이터 처리, Part 1: 시작"(M. Tim Jones저, developerWorks, 2010년 5월): 이 기사는 — 시리즈의 첫 번째 — HDFS(Hadoop file system)와 일반적으로 사용되는 노드 유형을 비롯한 Hadoop 프레임워크에 대해 살펴본다. 단일 노드 Hadoop 클러스터를 설치 및 구성하는 방법을 학습한 후 MapReduce 애플리케이션에 대해 자세히 설명한다. 마지막으로 Hadoop의 핵심 웹 인터페이스를 사용하여 Hadoop을 모니터링 및 관리하는 방법에 대해 살펴본다. 또한 Part 2와 Part 3도 참조한다.
- "클라우드에서 MapReduce 및 로드 밸런싱 사용하기(Kirpal A. Venkatesh 외 저, developerWorks, 2010년 7월): Hadoop MapReduce 및 가상화로 노드 성능을 개선하는 방법을 배워보자.
- "A profile of Apache Hadoop MapReduce computing efficiency, Part 1"(Paul Burkhardt저, Cloudera Development Center, 2010년 12월): MapReduce 애플리케이션이 얼마나 효율적으로 컴퓨팅 자원을 사용하는지에 대한 두 개의 파트로 된 설명이다. 처음 반은 Hadoop MapReduce 애플리케이션을 평가하는 것과 관련되는 컴퓨팅 효율성의 개요이다.
- "Hadoop companies everywhere"(Alex Handy저, SD Times, 2009년 7월): 회사는 매일 데이터를 더 많이 생성하지만, 이들 중 많은 수가 비즈니스 인텔리전스를 이끌어내지 않는다. 이는 기회라고 쓰고 Handy라고 읽는다.
- 이런 기술 주제와 다른 기술 주제에 대한 서적 정보는 Java technology bookstore를 참조한다.
- developerWorks Java 기술 영역: Java 프로그래밍과 관련된 모든 주제를 다루는 여러 편의 기사를 찾아보자.
제품 및 기술 얻기
- Hadoop MapReduce 다운로드: Apache Software Foundation 프로젝트.
- opencsv 받기: SourceForge에서 다운로드한다.
토론
- developerWorks 커뮤니티에 참여하자. 개발자가 이끌고 있는 블로그, 포럼, 그룹 및 Wiki를 살펴보면서 다른 developerWorks 사용자와 의견을 나눌 수 있다.
Andrew Glover는 Stelligent Incorporated의 사장이다. 회사들이 코드 품질을 일찍 그리고 자주 모니터할 수 있게 하는 효과적인 개발자 테스팅 전략과 지속적 통합 기법으로 소프트웨어 품질 문제를 해결하는 것을 돕고 있다. Andy의 저서 목록은 그의 블로그를 보라.