클라우드 컴퓨팅은 대규모의 데이터가 모이는 곳일 뿐 아니라 맵리듀스(Map Reduce)와 같은 병렬분산 처리 기법을 통해 거대 규모 데이터의 신속한 처리 비용을 급격히 하락 시켜 빅데이터 분석의 경제성을 획기적으로 개선하였다.
그런데,,, 도대체 왜 빅데이터에서 맵리듀스의 개념을 사용하는 걸까요?
빅데이터는 양이 워낙 많기 때문에 처리 프로세스는 최대한 단순하게 만들어야 합니다. 그래야 수많은 서버에 흩어서 병렬로 처리할 수 있거든요. 처리의 순서가 중요하다든지 실패했을때 다시하려면 몇단계 전으로 돌아가야 한 다든지 하면 대략난감해지니까요.
이를 위해서는 기준이 되는 값은 하나!이어야 프로세스가 단순합니다. 그래서 기준이되는 값인 키가 하나인 맵 구조를 선택한거구요.
키에 대한 실제 처리는 밸류(값)를 가지고 하게 되는데 여기에 수행 하는 연산도 역시 단순해야 합니다. 어떤식이냐면 교환법칙과 결합법칙이 성립해야 하죠. 임의의 서버에서 임의의 순서로 두 개의 맵을 선택해서 연산을 수행하더라도 최종결과는 늘 같아야 병렬처리가 가능 하니까요.
개념을 이해하기 위해서, 맵리듀스를 사용하는 패턴을 조금 더 자세하게 살펴볼께요.
예를 들어 쇼핑몰 사용자의 사용 로그가 아래와 같이 남는다고 가정 해볼께요.
사용일자:사용자아이디:행동유형:관련금액
-----------------------------------------
20150305 0930:chulsoo:addToCart:0
20150305 1002:chulsoo:buy:33000
...
쇼핑몰을 방문한 사용자를 집계하고 싶을때는
로그를 한 줄씩 읽으면서 (사용자아이디, 1) 형태로 맵을 만듭니다.
리듀스 할때 밸류를 서로 더해 주셔도 되고, key의 개수를 세어주는 함수가 제공된다면 그걸 그냥 호출하면 됩니다.
대략 적으로 코드 형태를 보여드리자면 이런 식입니다. 일종의 pseudo code랄 수 있겠네요. :)
map(사용자아이디, 1)
reduceByKey((a,b) => a+b)
맵을 만들때는 로그의 한 줄을 읽어서 적당한 부분을 잘라내는 파싱 작업이 먼저 이루어져야 하죠. 그래야 map에 저렇게 사용자 아이디를 넣어줄 수 있으니까요.
그리고 reduceByKey에 나오는 a,b는 두 개의 맵을 들고 연산을 수행할때, 각각의 밸류값 입니다. 키는 reduceByKey라는 이름이 알려주듯 같은 키 값을 가진 맵들끼리 계속해서 연산을 해서 맵의 숫자를 줄이는 거죠. 최종적으로는 그 키를 가지는 맵이 한 개 남을때 까지요. 그러니까 키는 정해줄 필요가 없고 첫번째 맵의 밸류 a와 두번째 맵의 밸류 b를 가지고 어떤 연산을 수행할 것인지 (위 예제에서는 더하기(+) 네요) 만 정해 주면 됩니다.
map(행동유형, 1)
reduceByKey((a,b) => a+b)
당일에 특정행동에 관련된 금액의 총계를 뽑고 싶을때는
사용일시가 당일인 건을 한 줄씩 읽으면서 (행동유형, 관련금액) 형태로 맵을 만들고,
리듀스 처리에서는 키가 같은 두 개의 맵에 만날때마나 밸류값을 서로 더해주는 함수를 선언하면 됩니다.
출처: https://cskstory.tistory.com/entry/맵리듀스-MapReduce-이해하기 [아는 만큼]
사용일시가 당일인 건을 한 줄씩 읽으면서 (행동유형, 관련금액) 형태로 맵을 만들고,
리듀스 처리에서는 키가 같은 두 개의 맵에 만날때마나 밸류값을 서로 더해주는 함수를 선언하면 됩니다.
map(행동유형, 관련금액)
reduceByKey((a,b) => a+b)
사용자별 행동별 건수와 같이 두가지 이상의 조건을 조합하고 싶은 경우에는요,
그 조건을 적절하게 이어붙여서 키 값을 만드세요.
한 줄씩 읽으면서 (사용자아이디_행동유형, 1) 형태로 맵을 만드는 것 처럼요.
그리고 나서 리듀스 처리를 하고,
이후에 이걸 다시 파싱해서 DB에 넣어서 조회하거나 하는 방식으로 사용할 수 있습니다.
map (사용자아이디_행동유형, 1)
reduceByKey((a,b) => a+b)