Fault-tolerant 시스템과 Erlang 프로그래밍

2009/03/20 18:31

복사 http://blog.naver.com/oomymy/120065457361

Erlang을 공부한지 몇달이 되어 가고, Programming Erlang 책을 두번을 넘게 읽었는데,

사실 이 언어를 통해 얻으려고 했던 바에 비해 실제 책을 읽고 나서 드는 감흥은 그리 크지 않은 것 같았다.

일단 가장 먼저 드는 문제는 역시 Erlang이 함수형 언어이기 때문에 여지껏 내 문제 해결 방식 및 사고 과정을 다소 수정해야 한다는 점, 그리고 Erlang이 Prolog에서 발전한 언어이기 때문에 문법적으로 이질적이라는 점이다. (C 계열 언어들은 모두 ;을 통해 문장을 종료하지만, Erlang은 종료는 .이지만 가끔 ,나 ;이 들어가는 경우가 있다. 이 이질적인 문법을 익히느라 매우 힘들었다.)

하지만, 문법을 익히고 코드를 들여다 보는 것 외에 이 Erlang을 만든 조 암스트롱의 박사학위 논문을 보니 Erlang의 역사와 설계 철학이 정말 잘 설명되어 있는 것을 발견했다. 게다가 그 부분을 읽고 나니, 내가 예전에개발에참여하면서 경험했던 통신 장비의아키텍처와 Erlang이 지향하는 시스템의 아키텍처가 매우 유사한 부분이 있다는 점을 깨닳았다. 설명을 위해 통신장비의 구조에 대해 간단히 살펴보자.

통신장비는 Fault-tolerance가 매우 중요한 요구사항이다. 시스템에 장애를 최소화하고 장애가 있더라도 즉시 대체 장비가 작업을 이어 받아서 서비스에 영향을 줘선 안 된다. 이 take-over 시간도 매우 짧아야 한다. 이를 위해 통신 장비를 다음과 같이 설계한다. (OS는 Unix며, 언어는 C를 이용했음)

(1) 가장 먼저 전체 시스템의 기능을 여러 독립적으로 동작 가능한 컴포넌트로 쪼갠다. 가령 프로토콜 스택, 데이터 저장소, 로직 처리, 모니터링, 통계 및 상태 정보등등이다. 그리고 이러한 컴포넌트들은 독립된 OS 프로세스로 작성한다. 이렇게 되면 각 컴포넌트들은 OS에서 제공하는 Protection-domain상에서 돌게 되어 상대방의 장애에도 전혀 영향을 받지 않게 된다. 예를 들어, 로직 처리하는 컴포넌트가 죽더라도 프로토콜 스택은 본래 기능을 정상적으로 수행할 수 있는 것이다.

(2) 이들간의 공유 자원을 최소화 하고 모든 통신은 내부 mssage queue를 통해 수행한다. 한 컴포넌트가 다른 컴포넌트에게 작업을 요청하기 위해선 message queue를 통해 메시지를 전송한다. 이때 메시지 전송은 모두 비동기식으로 이뤄진다. 즉, 메시지를 보내고 응답을 기다리지 않고 즉시 다른 일을 수행하는 것이다. 이는 역시 상대방 컴포넌트의 상태에 따라 현재 컴포넌트가 받는 영향을 최소화하기 위함이다.

(3) 한 장비의 외부에는 다른 장비를 두고 이 장비에는 똑같은 셋의 컴포넌트들을 실행시켜둔다. (일명 replication이다) 이 slave장비의 컴포넌트들은 master 장비의 컴포넌트가 장애가 나는지 안 나는지를 확인하고 있다가 장애가 발견되면 즉시 자신이 role을 이어 받아 작업을 수행한다.

이러한 fault-tolerant 시스템을 만들기 위해선 위의 기능들을 일일히 다 고민하고 구현해야 한다. 어떤 기능들을 프로세스로 분리시킬 것인지, 이들간의 효율적인 통신은 어떻게 하며, 그 통신 상대가 내부에 있을 때, 외부에 있을 때를 구분하지 않고 모두 한가지 semantic으로 다룰 수 있어야 하며, 외부에서 프로세스의 정상/비정상 종료를 감시하는 메커니즘은 어떻게 구현할 것인가...

Erlang은 이러한 Fault-tolerance를 언어적 측면에서 지원한다. 조 암스트롱이 본인의 박사학위 논문에서도 밝히고 있다시피, Erlang은Ericsson에서 80~90년대에 개발한 언어로 이미 내부적으로 많은 통신장비들이 Erlang으로 작성되어 매우 안정적으로 동작하고 있다고 한다. Erlang은 위의 개념을 다음과 같은 방법으로 제공한다.

1. Erlang은 thread와 비슷한 개념으로 Process를 제공한다. 이 프로세스는 OS의 프로세스와 헷깔리면 안 되는데, OS thread와 OS process 그 중간쯤 되는 것 같다. (lightweight하다는 점에서 thread와 비슷하고, protection-domain을 제공한다는 점에서 process와 비슷하다)무엇보다 모든 변수가 다 immutable이다. 한번 설정된 변수는 절대 바꿀 수 없다. 따라서 애시당초 thread동기화를 위한 lock이라는 개념이 필요하지 않는다. 게다가 Erlang process는 thread에 비해 매우 가볍다. 수만개를 생성해도 매우 빠른 시간에 처리되는 점이 매우 인상적이다. (예전 java의 green thread와 비슷하게 ErlangVM이 애플리케이션 레벨 쓰레드를 만들고 스스로 스케쥴링을 하는 방식이 아닐까 생각된다)

+ Recent posts