장발의 개발러

Java development 2.0: Hadoop MapReduce로 대용량 데이터 분석 본문

개발이즈 마이라이프/DB & BigData

Java development 2.0: Hadoop MapReduce로 대용량 데이터 분석

장발의 개발러 2012. 5. 22. 17:44

출처: http://www.ibm.com/developerworks/kr/library/j-javadev2-15/index.html?ca=drs-


Google이 2001년에 이미지 검색 기능을 실행했을 때, 2억 5천만 개의 인덱스된 이미지를 보유했다. 십 년이 지나지 않아, 이 검색 거인은 100억 개 이상의 이미지를 인덱스했다. 분당 35시간의 컨텐츠가 YouTube로 업로드된다. Twitter는 평균적으로 매일 5천 5백만 건의 트윗을 처리한다고 주장한다. 올해 초에 그 검색 기능은 매일 6억 개의 쿼리를 로깅했다. 대용량 데이터를 논의할 때 대용량이란 바로 그 정도이다.

이 시리즈의 정보

처음 Java 기술이 발표된 이후로 Java를 개발하는 과정은 급속도로 변화되었다. 오픈 소스 프레임워크와 신뢰할 수 있는 임대용 전개 인프라 덕택에 Java 애플리케이션을 신속하고 저렴하게 어셈블하고 테스트하고 유지할 수 있게 되었다. 이 시리즈에서 Andrew Glover는 이러한 새로운 Java 개발 패러다임을 가능하게 하는 다양한 기술과 도구를 탐구한다.

이러한 엄청난 규모의 데이터는 대기업, 대학 및 정부 — 엄청나게 비싼 슈퍼컴퓨터를 구입할 수 있으며 이를 계속 실행할 직원을 가용할 수 있는 단체 —에 국한되었다. 오늘날 스토리지 비용의 절감과 프로세싱 성능의 상용화를 통해 중소기업 및 일부 개인들도 동일한 데이터를 저장하고 마이닝하기 시작하여, 애플리케이션 혁신의 흐름을 발전시킨다.

대용량 데이터 혁명이 가능한 기술 중 하나는 MapReduce이다. 이는 엄청난 규모의 분산 데이터 세트를 처리하기 위해 Google이 개발한 프로그래밍 모델 겸 구현 방식이다. 이 기사에서 필자는 Apache의 오픈 소스 MapReduce 구현 방식인 Hadoop을 소개한다. 이는 클라우드 컴퓨팅의 킬러 앱(killer app)이라고도 한다.

Hadoop 정보

Apache의 Hadoop 프레임워크는 본질적으로 대용량 데이터 세트를 분석하기 위한 메커니즘이며, 이는 반드시 데이터 저장소에 수용하지 않아도 된다. Hadoop은 MapReduce의 거대한 데이터 분석 엔진을 요약하여 개발자들이 액세스하기에 더 쉽게 만든다. Hadoop은 무수한 노드로 확장하여 데이터 정렬과 관련된 활동 및 조정을 모두 처리할 수 있다.

Hadoop은 수많은 기능과 구성을 통해 놀랍도록 유용하고 강력한 프레임워크가 된다. Yahoo!와 무수한 다른 조직들은 산더미 같은 비트와 바이트들을 분석하기 위해 이를 효율적인 메커니즘이라고 인식했다. 또한 Hadoop은 단일 노드에서 작업하기에 매우 간편하다. 즉, 분석할 데이터가 어느 정도 있고, 제네릭을 비롯한 Java 코드에 익숙하기만 하면 된다. Hadoop은 또한 Ruby, Python 및 C++로 작업한다.

MapReduce에 대한 추가 정보

이 시리즈의 독자라면 이미 MapReduce가 작동하는 것을 두 세 번 확인했다. "Java development 2.0: CouchDB와 그루비의 RESTClient를 이용한 REST"에서 필자는 CouchDB가 뷰를 위해 MapReduce를 어떻게 활용하는지 시연했으며, MapReduce가 MongoBD 문서를 처리하기 위한 메커니즘이 되는 "Java development 2.0: MongoDB: (적절한) RDBMS 이동 기능을 제공하는 NoSQL 데이터 저장소"에서 이를 한 번 더 사용했다.

대용량 데이터 세트를 처리하기 위한 개념적인 프레임워크로서 MapReduce는 다수의 컴퓨터를 사용하여 분산된 문제 해결을 위해 고도로 최적화되었다. 프레임워크는 이름이 암시하는 대로 두 가지 함수로 구성된다. map 함수는 대용량 데이터 입력을 취하여 더 잘게 나누도록 설계되었으며, 그러면 이를 통해 어떠한 작업을 할 수 있는 다른 프로세스로 전달한다. reduce 함수는 map으로 수집되는 개별 응답을 요약하고 최종 출력으로 이를 렌더링한다.

Hadoop에서 Hadoop의 자체적인 기본 클래스를 확장하여 mapreduce 구현을 정의한다. 구현은 입력 및 출력 형식과 함께 이를 지정하는 구성으로 함께 묶인다. 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

Hadoop 설치

Hadoop을 이전에 설치하지 않았다면 이제 설치하자. 먼저, 최신 바이너리를 다운로드하고, 이를 압축 해제하여 경로에 Hadoop의 bin 디렉토리를 설정한다. 이렇게 하면hadoop 명령을 직접 실행할 수 있다. Hadoop을 사용하면 앞으로 확인하는 대로 java 명령을 호출하는 것이 아니라hadoop 명령을 실행해야 한다. Java 바이너리 파일(예를 들어, map reduce 구현을 표현함)을 찾을 수 있는 것과 같이 옵션을 hadoop 명령으로 전달시킬 수 있다. 필자의 경우에 jar 파일을 작성하여, jar 내에서 실행하려는 작업이 어느 것인지 Hadoop에 알린다. 또한 필자의 애플리케이션을 Hadoop의 클래스 경로로 실행하는 데 필요한 추가 바이너리도 추가한다.

이제 12월 12일에 98개의 항목 또는 98개의 기록된 지진이 있었음을 알게 되었다. 행 아래로 이동하여 12월 11일, 10일 등에 grep을 수행할 수도 있을 것이다. 하지만, 그것은 필자가 생각하기에는 지루하다. 더욱 나쁜 것은 이를 이끌어 내기 위해 파일에 어느 날짜가 있는지 알아야 한다는 것이다. 필자는 그 내용에 실제로 신경을 쓰지 않으며, 어떠한 경우에는 그러한 정보에 액세스 권한이 없을 수 있다. 실제로 필자는 어느 7일 범위에서나 주어진 각 날짜의 숫자만 알고자 하고, Hadoop을 통해 그러한 정보를 간편하게 얻을 수 있다.

Hadoop은 필자의 첫 번째와 두 번째 질문에 응답하는 정보의 몇 가지 부분만 필요로 한다. 다시 말해서, 처리할 입력이 어느 것이며, mapreduce를 어떻게 다루느냐이다. 또한 모두 함께 묶는 작업도 제공해야 할 것이다. 하지만, 그 코드에 작업을 시작하기 전에 전부 필자의 CSV 데이터 순서로 되어 있는지 확인하는 데 수분이 걸릴 것이다.

opencsv로 데이터 구문 분석

지진 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으로 형식화했다.

Hadoop의 map 및 reduce

이제 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이다.

Hadoop Job 정의하기

이제 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이 필자가 수행하려는 바로 그것을 수행했다는 점도 인식하길 바란다. 필자의 범위 내 모든 날짜에 대해 지진 발생 수를 깔끔하게 표로 만들었다.

또 다른 Mapper 쓰기

다음으로, 지진이 발생하는 위치를 알아내고, 어느 위치가 날짜 범위에서 대부분의 지진을 로그하는지 어떻게든 빠르게 측정하고자 한다. 자, 아마 추측한 대로, 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 프로그래밍과 관련된 모든 주제를 다루는 여러 편의 기사를 찾아보자. 

제품 및 기술 얻기

토론

  • developerWorks 커뮤니티에 참여하자. 개발자가 이끌고 있는 블로그, 포럼, 그룹 및 Wiki를 살펴보면서 다른 developerWorks 사용자와 의견을 나눌 수 있다. 

필자소개

Andrew Glover 사진

Andrew Glover는 Stelligent Incorporated의 사장이다. 회사들이 코드 품질을 일찍 그리고 자주 모니터할 수 있게 하는 효과적인 개발자 테스팅 전략과 지속적 통합 기법으로 소프트웨어 품질 문제를 해결하는 것을 돕고 있다. Andy의 저서 목록은 그의 블로그를 보라.