멤베이스가 Erlang을 사용하는 이유

점점 더 자주 (Erlang이 점점 더 대중화되고 있기 때문에), Membase가 왜 Erlang 를 클러스터 관리 및 프로세스 감독 구성 요소로 사용합니다. 사람들이 제안하는 일반적인 대안은 Java, C++입니다, Python, Ruby그리고 최근에는 node.js 그리고 Clojure (Erlang을 사용할 수 없다면 제가 가장 먼저 선택했을 것입니다).

Erlang을 사용하는 데는 분명 많은 단점이 있습니다. 무엇보다도 빌드, 번들링 및 지원해야 하는 또 다른 런타임 환경이라는 점입니다. Linux 및 OS X의 Python 시스템에 의존하고 있으며 다음을 사용합니다. py2exe 를 사용하여 Windows용 실행 파일을 빌드할 수도 있지만, 실제로는 Erlang을 빌드하고 번들로 제공합니다. Java를 사용하면 이미 Java가 설치되어 있는 시스템에 의존할 수 있는데, Linux에서는 조금 더 어렵지만 Windows에서는 더 쉽습니다. 또한 Java NodeCode 모듈을 실행하려면 결국 Java 런타임이 필요합니다.

게다가 Java나 C++, 또는 제가 언급한 다른 대체 언어들만큼 Erlang을 아는 프로그래머는 많지 않습니다. 구문과 의미론이 특이하기 때문입니다. 프롤로그 의 뿌리, 동시적이고 기능적인 특성, 그리고 1986년부터 사용되어 발전해 온 실용적인 언어라는 사실에 주목했습니다. Membase의 엔지니어링 팀에서는 4명이 Erlang 컴포넌트를 작업할 수 있고, Erlang 코드가 충분히 작아 누구라도 쉽게 유지 관리할 수 있기 때문에 문제가 되지 않았습니다. 그러나 자체 개발자와 커뮤니티 기여자 모두 Erlang을 모르는 경우 클러스터 관리 서브시스템에 기여할 수 있는 기준이 높아진 것은 분명합니다.

그만한 가치가 있습니다. Erlang(사실 대부분의 사람들이 "Erlang에는 X가 있다"고 말할 때 말하는 Erlang/OTP)은 처음부터 새로 만들거나 기존 라이브러리를 조합해서 사용해야 했던 많은 작업을 즉시 수행할 수 있습니다. 그것의 동적 유형 시스템 그리고 패턴 매칭 (알라 하스켈 및 ML) 덕분에 Erlang 코드는 몇 줄의 코드로 많은 작업을 수행할 수 있는 것으로 알려진 Python이나 Ruby보다 훨씬 더 간결한 경향이 있습니다.

Erlang을 사용함으로써 얻을 수 있는 가장 큰 장점은 다음과 같은 기본 지원입니다. 동시성. Erlang은 동시 작업을 "프로세스"로 알려진 메시지 전달(패턴 매칭을 활용!)을 통해서만 서로 통신할 수 있습니다. 배우 모델 를 사용할 수 없습니다. 이것만으로는 동시성 관련 버그의 전체 클래스를 완전히 불가능하게 만듭니다. 반면 교착 상태를 완전히 방지하지 못함이런 식으로 코드를 작성할 때 잠재적인 교착 상태 시나리오를 놓치는 것은 매우 어렵습니다. 물론 가능 를 사용하여 액터 모델을 구현할 수 있으며, 실제로 이러한 구현은 불완전하거나 스레드 사용을 기대하는 기존 라이브러리와의 임피던스 불일치로 인해 어려움을 겪고 있습니다.

Erlang 프로세스는 서로 격리되어 있을 뿐만 아니라 매우 가볍습니다. 단일 Erlang VM에서 25만 개의 프로세스를 쉽게 실행할 수 있습니다. 생성 비용도 매우 낮기 때문에 재사용을 위한 어리석은 해킹도 불필요합니다. 동일한 메모리 공간에서 실행되고 소프트웨어로만 격리되어 있기 때문에 메시지 전달 속도가 매우 빠르며, 대부분의 경우 메시지의 데이터를 복사해야 하지만 메시지 크기가 작기 때문에 Erlang 프로세스는 독립적으로 가비지 컬렉션을 수행할 수 있습니다.

OTP는 프로세스를 "수퍼비전 트리"로 정렬하여 수퍼바이저 프로세스가 수퍼바이저가 될 수 있는 하위 프로세스를 모니터링하고 충돌 시 해당 프로세스와 잠재적으로 모든 종속 프로세스를 재시작합니다. 프로세스 격리와 함께, 이것은 Erlang 애플리케이션을 매우 내결함성으로 만듭니다. 클러스터 관리 하위 시스템 내의 모든 Erlang 프로세스(루트 수퍼바이저 제외)는 Membase를 다운시키지 않고도 충돌을 일으킬 수 있습니다. 실제로 저희는 이를 매우 잘 활용하고 있습니다. 프로세스에서 예기치 않은 일이 발생하면 일반적으로 충돌을 일으킨 후 다시 시작하여 정상 상태로 되돌려 놓습니다. 예를 들어, 로컬 멤캐시드 프로세스에 대한 관리 연결을 관리하는 프로세스는 연결 시간이 초과되거나 예상치 못한 오류가 반환되면 간단히 충돌을 일으킵니다. 이렇게 하면 오류 처리가 시작과 정확히 동일하게 이루어지므로 버그가 숨을 곳이 줄어들고 테스트가 쉬워집니다.

복잡한 애플리케이션을 상호 작용하는 프로세스 집합으로 쉽게 구조화할 수 있도록 Erlang/OTP는 표준 "행동' 모듈이 구현할 수 있습니다. 가장 일반적인 것은 gen_server를 사용하여 요청에 대한 콜백이 있는 기본 서버를 구현하는 일반적인 서버 동작을 구현합니다. Gen_fsm 는 유한 상태 머신을 구현하고 gen_event 는 이벤트 핸들러와 이벤트 매니저를 구현하기 위한 것입니다.

Erlang의 메시지는 같은 노드에 있는 프로세스에 보내는 것처럼 다른 노드에 있는 프로세스에 쉽게 보낼 수 있으며, 이는 프로그래머에게 완전히 투명합니다. Erlang/OTP에는 분산 처리에 도움이 되는 여러 모듈이 있습니다. 예를 들어, "글로벌" 모듈은 Google의 Chubby 잠금 관리자와 유사한 글로벌 이름 및 잠금의 공통 레지스트리를 제공합니다. OTP의 '분산 애플리케이션'은 특정 프로세스 집합이 하나의 노드에서만 시작되도록 하는 방법을 제공합니다. Mnesia는 강력한 일관성을 보장하는 분산형 DBMS로, 통계 저장에 사용합니다.

Erlang은 라이브 시스템의 디버깅 및 패치에 대한 탁월한 지원을 제공합니다. 결국, 가동 시간이 99.999%인 시스템을 구축하기 위해 개발되었습니다. 암호화 쿠키 노드가 서로를 인증하는 데 사용하는 암호화 쿠키를 알고 있다면, 클러스터에 다른 Erlang 노드를 연결하고 다른 노드에서 "이 모듈 다시 로드"와 같은 임의의 명령을 실행하는 것은 간단합니다. 이러한 기능은 버그를 수정하거나 해결해야 하는데 코드를 교체하기 위해 클러스터나 단일 노드를 제거할 수 없을 때 매우 유용합니다. 또한 테스트 또는 당사(또는 고객)가 REST API에서 아직 구현되지 않은 클러스터 상태를 변경하려는 상황에서도 매우 유용합니다.

결국 진짜 문제는 다른 언어로 클러스터 관리를 구현할 수 있었는지 여부가 아니라 결과물의 노력과 유지 보수성에 관한 문제입니다. 다른 환경이었다면 Erlang/OTP가 제공하는 기능 중 적어도 일부를 다시 구현해야 했을 것이지만, 우리는 다른 환경이 제공하는 기능을 다시 구현한 적이 없습니다.

이 문서 공유하기
받은 편지함에서 카우치베이스 블로그 업데이트 받기
이 필드는 필수 입력 사항입니다.

작성자

게시자 션 린치

댓글 남기기

카우치베이스 카펠라를 시작할 준비가 되셨나요?

구축 시작

개발자 포털에서 NoSQL을 살펴보고, 리소스를 찾아보고, 튜토리얼을 시작하세요.

카펠라 무료 사용

클릭 몇 번으로 Couchbase를 직접 체험해 보세요. Capella DBaaS는 가장 쉽고 빠르게 시작할 수 있는 방법입니다.

연락하기

카우치베이스 제품에 대해 자세히 알고 싶으신가요? 저희가 도와드리겠습니다.