서울시 지진 해일 데이터로 Hadoop MapReduce 해보기
~일간~ 두더지 탈출기 (부제. 삽질 멈춰!…)
Seoul Emergency 프로젝트를 진행하며 발생한 에러를 정리합니다.
데이터 준비하기
우분투에서 한글사용하기
요거 따라하기
중요!!!
- 중간에 install 하다가 인터넷 커넥션 에러 뜰 경우 cmd 창에서 apt
sudo apt-get update
명령어로 업데이트해주기 -
상단바에서 한글 꼭 설정해줘야함
서울시 열린데이터 광장에서 데이터 다운로드
- 파이어폭스에서 서울시 열린데이터 광장 접속한 뒤 csv 파일 다운로드
- 파일명 한글+띄어쓰기 있으면 나중에 귀찮아지므로 적절한 영어로 바꿔주기
-
파일 열어봤을 때 외계어로 되어있으면 인코딩 변경해주기
- cmd 창에서 아래 명령어 실행
iconv -c -f euc-kr -t utf-8 "서울특별시 지진해일대피소 정보_20180806.csv" > seoul_earthquake.csv
위도와 경도를 추출하는 맵 리듀스
map 함수 실행 시 1라인-1데이터 매칭 실패
map() 함수는 csv 파일의 한 라인을 읽어들이고 실행함
아래처럼 한 줄에 하나의 대피소 정보만 담겨있는 경우는 땡큐지만,,,
개포은행나무공원,지진대피소,옥외대피소,공원,서울특별시강남구개포동1220,서울특별시강남구개포동1220,37.4850738,127.0470484,1642,1990,Y,000-0000-0000,,강남구,,,,미적용,,,,1,,,강남구,02-3423-6942,2018-08-06
문제의 시작은 난곡초
부터;;
난곡초등학교운동장,지진대피소,옥외대피소,운동장,서울특별시관악구난곡로35길102,서울특별시관악구난곡로35길102,"37.4884257
48688975","126.9435449
2850962",3441,4170,Y,02-855-2131,,관악구,,,,미적용,,,,1,,,관악구,02-879-5812,2018-08-06
쓸데없이 위도, 경도 부분이 잘려 엔터가 들어가 줄이 바뀐 것처럼 저장되어 있다.
1라인에서 가능한 위도와 경도만 뽑아내기
하는 수 없이 위도, 경도의 형식을 바탕으로 데이터 추출 시도
- 콤마(”,”) 를 기준으로 split
- 큰따옴표 trim
- 띄어쓰기 있으면 붙이기
- 위도(00.0000)와 경도(000.0000) 형식인 문자열만 채택
이때 key 는 위도는 “lat : ”, 경도는 “long : “으로 설정한다.
map 함수
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
String line = value.toString();
// 1. 콤마(",") 를 기준으로 split
String[] splitArr = line.split(",");
// Long offset = ((LongWritable)key).get();
for (int size=splitArr.length, i=0; i<size; i++) {
String wordStr = null;
String pointStr = null;
String splitWord = splitArr[i];
// 2. 큰따옴표 trim
splitWord = splitWord.replaceAll("\"", "");
// 3. 띄어쓰기 있으면 붙이기
splitWord = splitWord.replaceAll(" ", "");
if (splitWord.length() <= 3) continue;
// 4. 위도(00.0000)와 경도(000.0000) 형식인 문자열만 채택
if (splitWord.charAt(2) == '.') {
wordStr = "lat : ";
pointStr = splitWord;
word.set(wordStr);
point.set(pointStr);
context.write(word, point);
} else if (splitWord.charAt(3) == '.') {
wordStr = "long : ";
pointStr = splitWord;
word.set(wordStr);
point.set(pointStr);
context.write(word, point);
}
}
}
reduce 함수
InvertedIndex 예제에 적용해보기!
lat : 37.614593, 37.606786, 37.6103313, 37.611694, 37.593495,
…
long : 127.091652, 126.9625116, 127.0960772, 127.0218054, 127.09733,
…
산출물은 요렇게 모든 위도와 경도 데이터가 문자열로 추가된 형태가 된다.
public static class IntSumReducer
extends Reducer<Text,Text,Text,Text> {
// variables
private Text result = new Text();
// key : a disticnt word
// values : Iterable type (data list)
public void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
String valueString = " ";
for ( Text val : values ) {
valueString += (val.toString() + ", ");
}
valueString = valueString.substring(0, valueString.length()-2);
result.set(valueString);
context.write(key,result);
}
}
하둡 실행하기
하둡 공식 따라하기
// Project 디렉토리에서
> ant
> hdfs dfs -mkdir sub02_earthquake_test
> hdfs dfs -put ~/Downloads/seoul_earthquake.csv sub02_earthquake_test
> hadoop jar ssafy.jar sub02_earthquake sub02_earthquake_test sub02_earthquake_test_out
> hdfs dfs -cat sub02_earthquake_test_out/part-r-00000 | more
> hdfs dfs -cat sub02_earthquake_test_out/part-r-00001 | more
결과