서울시 지진 해일 데이터로 Hadoop MapReduce 해보기

~일간~ 두더지 탈출기 (부제. 삽질 멈춰!…)
Seoul Emergency 프로젝트를 진행하며 발생한 에러를 정리합니다.

데이터 준비하기

우분투에서 한글사용하기

요거 따라하기

Ubuntu 20.04 키보드 한글 입력 설정 하기

중요!!!

  • 중간에 install 하다가 인터넷 커넥션 에러 뜰 경우 cmd 창에서 apt sudo apt-get update명령어로 업데이트해주기
  • 상단바에서 한글 꼭 설정해줘야함

    Ubuntu 64-bit - VMware Workstation 16 Player (Non-commercial use only) 2022-03-10 오후 5_45_32.png

서울시 열린데이터 광장에서 데이터 다운로드

  • 파이어폭스에서 서울시 열린데이터 광장 접속한 뒤 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라인에서 가능한 위도와 경도만 뽑아내기

하는 수 없이 위도, 경도의 형식을 바탕으로 데이터 추출 시도

  1. 콤마(”,”) 를 기준으로 split
  2. 큰따옴표 trim
  3. 띄어쓰기 있으면 붙이기
  4. 위도(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

결과

Ubuntu 64-bit - VMware Workstation 16 Player (Non-commercial use only) 2022-03-10 오후 6_21_30.png

Ubuntu 64-bit - VMware Workstation 16 Player (Non-commercial use only) 2022-03-10 오후 6_22_11.png