Hadoop 클러스터를 실시간 서비스에 적용 가능할까요? 라는 질문에 대해서

위 질문은 어제 내 발표가 끝나고 어떤분이 했던 질문이였다.
어제 대다수의 질문이 hadoop(야후 그리드 시스템 구성이나 operation) 자체에 대한 질문이였다면(이런 질문은 confidential 이슈로 대부분 답변하지 않았다.)
그러나 이 질문은 가장 유일했던 hadoop을 이용한 알고리즘에 대한 질문이였다. 이 이야기를 좀더 심도깊게 이야기 하지 못한게 약간 후회되서 포스팅을 써본다.

변명을 하자면 어제 상당히 많은 분들이 질문과 명함교환을 요청하셔서 그랬다고 말씀드리고 싶다. ^^;

아주 짧은 시간 동안 말씀을 드렸지만 하도 정신이 없어서 ‘서비스에 다이랙트로 적용하는건 힘들다” 라고 답변을 드린거 같다.

나중에 그분이 추천시스템을 생각하고 있다고 한것 같았는데… 당연히 많은 Machine Learning 알고리즘 처럼 모델을 빌드하고 그 모델만을 이용해 output을 도출해 내는 그런 방식으로 생각을 가볍게 했었다.

일단 Hadoop을 이용해서 ML관련 어플리케이션을 만든다는건 모델을 빌드하는데 대부분 쓰인다. 예를 들어 분류기를 만들경우 분류 function의 각 weight값을 만드는데 hadoop을 쓸수 있다는 것이다. 그래서 background processing작업에 주로 쓰인다는것이다.

일단 모델이 빌드 되면 그 모델에 입력을 넣어서 결과를 뽑는건 아주 computation resource가 모델 빌드보다 훨씬 적게 드는 작업이다. 물론 확률 기반 알고리즘 같은 경우는 그 item의 확률을 구하는데 분산을 쓸수도 있겠지만 굳이 이 부분은 Hadoop을 쓰지 않아도 될 정도다.

일단 이분의 질문 의도가 user-based collaborative filtering 방법을 쓰려고 하는게 아닐까 하는 생각이 들었다. 하나의 user data가 들어 왔을때 다수의 data와 모두 비교를 하고 비슷한 것들을 묶어서 리턴을 받아야 될 작업이라면 충분히 이런 질문을 할 수 있을것이다.

대략적인 과정은 이럴것이다.

입력되는 user data와 그밖의 모든 데이터들의 쌍을 만들어 입력 시킨다.
(input user data, to compare user data)
map 함수에서는 이렇게 입력된 값의 유사도를 계산해서 그 유사도를 키로 하고 비교 대상이 되는 user데이터를 값으로 하는 데이터를 만들어 리턴한다.
그러면 combine 함수에 의해서 소팅이 되겠고(내림차순) reduce함수를 이용해 그대로 소팅된 값을 출력해서 그 상위에 나온것들을(가장 유사도가 큰것을) 추천에 쓰면 될것이다.

이런 작업을 hadoop을 이용해서 한다면 … 너무 특징적인 업무를 하는 거대한 platform을 사용한다고 해야 하나?
그리고 200ms의 서비스 리턴 속도를 내기엔 힘들거라 생각한다. 굳이 이런 방법으로 실시간에 하자면 비교할 차원을 줄여서 complexity를 줄여야 겠지만, 그렇게 하면 정확도가 떨어질것이다.

그래서 ML의 model을 빌드하는 방식과 유사한 item-based collaborative filtering 방법을 추천한다.  여기서 hadoop을 쓰는 이유는 유저 item data업데이트를 가장 최신의 것으로 빠르게 업데이트 할 수 있어서이다.
user data를 기반으로 가장 유사한 item항목들의 목록을 각 item마다 계산을 하는데 이것은 반드시 background로 돌아야 하는 작업이지만 실시간으로 많은 사용자를 대상으로 계산한다면 이 방법이 위 방법보다 나을 것이다.
실제 서비스 기반의 recommandation 엔진을 구현할때 위 방법을 사용하는걸로 알고 있고 처리시간을 단축하기 위해 hadoop을 적용하는것도 조금만 생각해보면 그림이 그려질거라 생각한다.

이 작업을 단순하게 생각하면 각 item마다 n^2의 complexity로 돌면서 각 item과 유사한 항목을 리턴받는 방식을 생각할 수 있는데 이건 너무 무식한 방법이다. 이것을 hadoop으로 돌린다면 n번의 mapreduce작업이 배치로 돌것이다. (hadoop의 특징을 전혀 살리지 못하는 작업이다. ㅡㅡ;)
물론 그 배치 작업은 single에서 돌때보다 훨씬 빠를것이다. 하지만 여기서 잠깐 더 생각을 해보자면 클러스터링 방법을 사용해서 유사한 것들끼리 미리 묶어 주는 작업을 hadoop을 이용해서 하자는것이다.
k-means 알고리즘 같은것을 이용해서 미리 묶어주고 그 묶어준 대상들 내에서면 유사도를 비교해서 각 item마다 정렬된 리스트를 리턴받으면 되지 않을까 한다.

내 결론은 어떤 terabyte데이터들간의 계산 결과의 freshness를 위해 hadoop을 쓰는데는 이견이 없지만, 첫번째 방법과같이 실시간으로 입력된 데이터를 모든 다른 데이터와 비교하는 서비스에 쓰이는것은 회의적이라는 것이다.

ps) 사내 클러스터에서 실험하다 중단했던 netflix 가 생각이 나는군.. 쩝

CC BY-NC 4.0 Hadoop 클러스터를 실시간 서비스에 적용 가능할까요? 라는 질문에 대해서 by from __future__ import dream is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.