Professional Documents
Culture Documents
얼랭 (Erlang) 으로 다중서버 기반의 분산처리 플랫폼 만들기
얼랭 (Erlang) 으로 다중서버 기반의 분산처리 플랫폼 만들기
Map/Reduce 란 무엇인가?
최근 몇 년간 구글의 면접에서 가장 흔하게 나온 문제가 이랬다.
분산 얼랭 (Distributed Erlang)
필자가 얼랭(Erlang)을 공부하고 이 언어가 Map/Reduce 같은 분산 알고리즘을 이용한 어플리케이션
개발에 최적화된 언어라고 언젠가 언급한 적이 있었다. 그것의 중심에는 spawn()함수의 편리성과
spawn()함수를 통해 나온 Process ID 값이면 어느 노드에 있든 프로세스건 핸들링이 가능한 분산얼랭
(Distributed Erlang)환경에 있었다.
이 분산얼랭 환경은 최적화가 되어 있어서 같은 머신 에서는 물론이고 개방된 네트워크간의
노드에서도 쉽게 운영이 가능한 장점이 있다. 그래서 이 분산얼랭을 이용하면 다수의 머신 에서
운영하나 마치 한대의 머신 에서 돌리는 것 같은 착각마저 불러 일으킨다.
Map/Reduce 모델하고 어울리는 점이 바로 이거다.
다수의 노드를 관리하기 편하고 수십 개 수백 개의 map 프로세스와 reduce 프로세스를 쉽게
생성하고 죽일 수 있기 때문이다. 또한 얼랭의 경량 프로세스는 OS 레벨의 프로세스하고의 비교를
불허할 정도로 가볍고 빠르다.
메시지 전달을 기반으로 한 함수형 언어의 특징을 가지고 있어 입력 값이 같으면 결과값은 항상
같다는 것을 보장하게 된다. 중간에 쓰레드 같은 게 들어와서 변수를 몰래 고치거나 그런 일이 절대
일어나지 않는다는 것인데, 이로서 얼랭 프로세스 한 개가 정상적으로 잘 돈다면 수백 개의 같은
얼랭 프로세스도 잘 돌게 된다는 것을 보장하게 된다..
마지막으로는 에러에 강건한(fault tolerant) 시스템을 만들 수 있다는 장점이 있다. 생성된
프로세스는 다른 프로세스와 쉽게 링크(link)가 되어 서로 프로세스 작동 여부를 감시할 수 있다.
따라서 어디서든 충돌이 일어나 프로세스가 죽으면 바로 프로세스를 되살릴 수 있다.
Broker Process
Map/Reduce 전체 프로세스를 스케줄링 하기 위한 프로세스. 실제 각 노드 프로세스 정보를 가지고
있고 Reducer 프로세스 정보도 가지고 있다. 모든 노드에 Map 프로세싱 작업의 진행 여부를
체크하고 각 노드에 Job 을 할당하며, Map 단계가 끝나고 나서는 각 Reduce 프로세스에 데이터를
할당한다.
Node Process
Broker 프로세스로부터 생성이 되며, Broker 프로세스로부터 데이터를 받아 휘하 Map
프로세스들에게 Job 을 할당한다. 데이터 처리 진행 여부를 체크하며 이를 Broker 프로세스에 리포팅
한다. Map 프로세싱 이외에 combine 이라는 최적화 작업이 각 Node 프로세스에서 수행되어 진다.
Map Processes
Node 프로세스로부터 생성이 되며 실제 map 작업을 하는 프로세스이다. Map 프로세스의 생성시
할당되는 map 함수에 따라 다양한 작업이 가능하다.
Reduce Processes
Broker 프로세스로부터 생성/파괴가 되고 각 노드에서 결과로 나오는 데이터를 받아서 최종 Reduce
프로세싱을 하게 된다. 역시 Reduce 함수를 교체해줌으로 인해 다양한 작업이 가능하다.
얼랭의 프로세스 자체가 메시지 전달(message passing)에 의해서 이루어 지기 때문에 이해를 위해
MSD(message sequence diagram)을 그려봤다.
사실 전체적인 메커니즘은 아래 MSD 에 다 나와 있다. 예제 소스코드와 메시지를 잘 매칭해서 보면
전체적인 윤곽을 파악하는데 큰 도움이 될 것이다.
따라서 지면이 좁은 관계로 세세한 설명 보다는 반드시 이해해야 되는 구현 원리를 설명해 보도록
하겠다.
node
node process:
process: (good,1),(good,1),(good,1),(good,1),(is,1),(is,1),
(good,1),(good,1),(good,1),(good,1),(is,1),(is,1),
(is,1),
(is,1), (the,1),
(the,1), (today,1),(weather,1),
(today,1),(weather,1), (weather,
(weather, 1)
1)
node
node process
process :: (good,4),
(good,4), (is,3),(the,1),(today,1),(weather,2)
(is,3),(the,1),(today,1),(weather,2)
예제 코드 테스트
예제로 쓰일 것은 Map/Reduce 프로그래밍의 “Hello world!” 격인 word count 예제이다.
주어진 문서에서 TAB 이나 공백 단위로 쪼개진 단어를 카운팅 하는 게 예제의 목적이다.
이를 위해 map 함수와 reduce 함수를 제작해보면 아래와 같다.
map_function(Line) ->
TokenList = string:tokens(Line, "\t\s"),
[ {Tok, 1} || Tok <- TokenList].
reduce_function(ValueList) ->
lists:foldl(fun(X, Accu) -> X + Accu end, 0, ValueList).
Code3. word count 예제의 map 함수와 reduce 함수
보시다시피 map 함수는 파일의 라인을 받고 이를 [ {Key, 1}, {Key2, 1} ] 리스트로 반환한다.
그리고 reduce 함수는 값들의 리스트만을 받아서 리스트 내부의 값들을 순회하면서 더한 결과를
리턴 한다.
이를 실험 하기 위해 필자가 미리 main()함수를 만들어 두었다.
가장 먼저 해야 될 것이 대상이 되는 머신 에서 분산 얼랭 쉘을 띄워 두는 것이다. 필자는 동일
서버에서 3 개의 터미널을 띄우고 테스트를 수행했다. 아마 서로 각기 다른 서버에 띄운다고 해도
크게 다르지 않을 것이다. .
우선 Node 프로세스와 Map 프로세스가 띄워질 2 개의 얼랭 쉘을 띄운다.
마지막으로 컴파일 된 코드가 존재하는 디렉터리로 이동해 Broker 프로세스와 Reduce 프로세스들이
띄워질 1 개의 얼랭 쉘을 띄운다.
(gogamza@freesearch)1> c(distmapreduce).
(gogamza@freesearch)1> distmapreduce:main(["distmapreduce.erl", "goguma@freesearch",
"gamza@freesearch”]).
main 함수에 들어가는 첫번째 인자는 프로세싱한 파일명이고, 나머지는 쉘을 띄운 node 정보이다.
이렇게 실행 시키면 distmapreduce.erl_word_count 라는 파일이 생성이 되는데 이게 바로 word
count 된 결과 파일이다.
만일 동일 네트웍상의 다른 머신에서 돌린다면 얼랭 쉘을 띄울시 아래와 같이 하면 된다.
gogamza@gogamza.freesearch:~$ erl –name gogamza –setcookie abc
필자가 3 대의 서로 다른 머신에서 돌려봤는데 정상적으로 처리가 된다면 아래와 유사한 화면이
출력될 것이다. (아래는 필자가 3 대의 서로 다른 머신에서 돌려봤을 때 출력된 로그이다. 독자 분들이
직접 돌려본다면 아래와 유사한 로그를 볼 수 있을 것이다.)
Now number of 2 nodes is avalible.
<8278.113.0> node init : 5 mapper processes is aviable!
<0.44.0> broker init : 3 reducer processes is aviable!
<8279.112.0> node init : 5 mapper processes is aviable!
<8279.112.0> node map process is done!
<8279.112.0> node combine process is completed
Map processing on <8279.112.0> node was completed
<8278.113.0> node map process is done!
<8278.113.0> node combine process is completed
Map processing on <8278.113.0> node was completed
reduce completed!
Cleaning Process!
마치며...
사실 짧은 지면에 Map/Reduce 및 분산 얼랭을 설명한다는 거 자체가 불가능 이였을지도 모르겠다.
하지만 둘 중에 하나만 독자들이 이해를 한다면 다른 하나를 다시 찾기에는 그리 오랜 시간이 걸리지
않을 거라 생각한다.
만일 이 섹션을 이해하기 힘든 독자 분들에게는 프로그래밍 얼랭(Programming Erlang)책의 10 장과
20 장을 참고하시는걸 추천한다.
필자는 이런 분산얼랭의 특징 때문에 기계학습(Machine Learning) 어플리케이션을 구현함에 있어서
얼랭을 사용했었다. 물론 지금까지 수십 대의 노드를 사용해야 할 정도로 큰 데이터를 학습시켜 보지
않았지만 얼랭은 잠재력 있는 최적의 선택이었다고 생각한다.
멀티코어, 대용량 데이터의 시대를 맞이하여 앞으로도 얼랭은 아마도 최적의 선택이 되지 않을
듯싶다. [이달의 디스크 : dist_mapreduce.zip]