2014년 8월 15일 금요일

Couchbase 사용기 - 1

Couchbase 을 도입해서 Web REST 기반의 서버를 제작했습니다. 실제 서비스를 제공중에 있구요. 동시접속 2만명 테스트도 진행했었는데, Couchbase 는 잘 버틴다는 표현을 쓰기 무색하게...한가로이 데이터를 처리하더라구요. 하나의 요청에 Couchbase 의 문서(Document) 갱신이 최소 2회가 이루어지는데도 말이죠. MariaDB with Galera Cluster 라면 몇 분 마다 한 번씩 SlowQuery 로그가 떨어질 환경이었는데 별 걱정 없이 프로그래밍 할 수 있게 해줘서 다행이다 싶었습니다.

하지만, 게임이 매우 잘되어서 저장공간이 부족해지거나, Log 를 Couchbase 에 담는다거나 해서 용량증설의 시기가 다가오면, 장비의 추가냐 램의 증설이냐를 따져야할 때가 옵니다. 보통은 서버에 램을 추가로 꼽는 것이 훨씬 비용이 저렴하기 때문에 램 증설(Scale-Up)을 고려하게 되지만, 문서의 크기가 점점 불어나서 저장 공간이 부족해질 때에 적합한 것이지 사용자가 늘어나서 증설의 필요성이 생긴 것이라면(다시 말해 문서의 개수가 많아졌을 경우) 장비의 추가(Scale-Out)가 필요하게 되었다고 판단해야 합니다.
이는 Couchbase 가 기본적으로 Sharding 을 지원하기 때문에 장비가 늘어나면 늘어날수록 문서(Document)가 각 서버에 분산 배치되어 처리되기 때문에 서버가 늘어날수록 요청이 서버수만큼 분산되어 전체 처리량을 늘릴 수 있게 되기 때문입니다.

그런데 살짝 딜레마에 빠지게 되는게 두 가지가 있습니다.

먼저, Couchbase 는 가상머신(Cloud Server인 AWS 나 UCloudBiz, 혹은 VMWare, Zen Server 등)보다는 실제머신을 사용할 것을 권합니다. 아무래도 가상머신들은 메모리를 공유하는 형태가 많기 때문에 이 부분에서 속도 문제나 오염 문제가 생길 가능성을 배제할 수 없을 것 같기도 하고, CPU 등의 설정이나 Couchbase 의 네트워크 환경의 문제도 약간 걸림돌이 될 수 있습니다.
특히 가상머신을 이용할 경우 하나의 공인IP 을 여러 가상머신이 공유해서 사용하는 경우가 대부분인데 Couchbase SDK 는 편리한 Connection Pool 을 이용해 접속을 하는 대신, 8091 와 11210 포트를 이용해 Pool 에 등록된 Couchbase Server 에 접속을 하기 때문에 포트 포워딩을 통해 각 서버에 접속할 수 있도록 해줄 수가 없습니다. 좀 더 자세히 설명하자면,


  1. Client 는 Server 의 8091 포트를 통해 접속 시도
  2. Server 는 Client 에게 Clustering 된 Server 접속정보(HOST:PORT 형식) 목록을 제공
  3. Client 는 Connection Pool 에 Server 목록을 저장
  4. 저장된 Server 목록을 이용해 각 Server 에 접속


위와 같은 동작 방식을 취하고, 이는 Couchbase SDK 뿐만 아니라 Couchbase Server 간에도 이와 같은 방식을 취하기 때문에 외부 접속시에만 포트 번호를 임의로 바꿔서 처리하는 포트 포워딩 방식의 처리도 쉽지 않습니다.
그리고, 처음에는 1 대의 머신으로 테스트를 하는 경우가 많아서 간과할 수 있는 부분이 있습니다. Couchbase 는 장비를 기존 Cluster 에 추가할 때에는 IP 혹은 Domain(FQDN)을 이용해서 기존 서버(신규 서버에서 기존 클러스터에 참여하려고 할 때) 혹은 신규 서버(기존 서버에서 신규 서버를 등록하려고 할 때)에 접속해서 연결을 하는데, 위의 2 번에서 돌려주는 Server 접속정보가 이 때 등록한 IP 혹은 Domain 이 됩니다. 그래서 가상머신에서 가상IP 을 이용해서 등록을 하게 될 경우 외부에서 Couchbase SDK 을 이용한 Client 연결이 불가능해질 수 있습니다.
이에 대한 해결 방법을 고민한 결과, 저는 hosts 파일을 모든 Client/Server 에 등록해서 연결하는 방식을 취하고 있습니다. IP 나 제대로된 DNS 을 이용할 경우 가상머신을 이용할 때에 꼬이게 되는 부분이 있어서 이렇게 처리했습니다. 혹시 더 좋은 방법이 있으신 분은 조언 부탁드립니다(zepinos@gmail.com).

또 다른 하나는, 실제 머신을 이용할 때입니다. 기업에서, 특히 저와 같이 게임 업계 쪽에서 Cloud 서비스을 이용하는 것은 바로 확장성입니다. Scale-Out 와 Scale-In(장비 줄이기) 가 매우 쉽기 때문입니다. 일반적으로 실제 머신을 이용하게 될 경우 IP 는 공인IP 을 직접 부여하는 경우가 많기 때문에 먼저와 같은 문제는 크게 고민거리가 안될 수 있습니다. 하지만, 실제 장비는 장비 추가가 급하게 이루어져야 할 때 크게 문제가 발생합니다. 장비의 도입까지는 서버 업체 및 사양 결정, 견적 요청, 납품 등의 프로세서를 거치는데 이 기간이 보통 수 주가 소비되는 경우가 많습니다. 서비스가 크게 흥행하게 될지 아닐지 모르는 상황에서 무턱대고 장비를 여러개 도입하기도 힘들고, 그렇다고 사양이 높다고 해서 성능이 올라가는 형태의 솔루션이 아니기 때문에 요청 숫자에 따른 장비 확보는 쉽지 않은 문제가 있습니다.
또한, Sharding 이 기본적으로 지원되어서 처리량을 늘려나갈 수 있는 장점이 존재하는 대신에 장비를 추가하거나 제거할 때에는 반드시 Rebalance 작업을 진행해야 합니다. 한 대의 장비에는 전체 문서(Document)의 1/N 만큼의 문서를 가지고 있고 해당 문서를 전담해서 처리한다고 생각하면 편한데, 서버를 제거할 경우에는 문서를 다시 1/(N-1) 만큼 나눠서 각 서버에게 재배치해야 하는 일이 발생한다는 것이죠. 그 작업을 Rebalance 라고 합니다. 아무리 메모리와 빠른 내부 네트워크를 이용해서 일을 처리한다고 해도 문서양이 많을 경우 수십분 이상 소요될 수 있는 작업이 됩니다. 물론 이러한 Rebalance 작업은 Live 환경에서 적용이 가능하기 때문에 작업 공지를 걸고 전체 서비스를 차단한 뒤 진행할 필요가 없어서 매우 좋긴 하지만 문제가 발생할 수 있다는 걱정 때문에 쉽사리 하지 못한다는 문제가 있습니다. 그리고, 각 서버는 Replica 라고 하는 백업 정보를 가지고 있는데 보통은 서버 대수보다 한 개 적게(N-1) 가지고 있습니다. 즉 1~3 번 서버가 존재한다면 Replica 는 2 개를 설정하는게 좋은데(Bucket 생성 시 선택할 수 있고, 언제든지 바꿀 수 있습니다) 1번 서버의 경우 메모리에는 자신에게 할당된 문서들을, Replica 에는 2 개의 백업(2, 3 번 서버에 할당된 문서)을 저장하게 되는 것입니다. 그래서 서버가 Rebalancing 없이 갑작스럽게 중지가 되어도 Replica 을 이용해서 문서 내용을 복구할 수 있습니다. 그리고 중지된 서버의 요청도 활성화된 서버가 Replica 의 내용을 메모리로 올려서 대신 제공해줍니다. 하지만, 실제 서버를 이용하게 될 경우 이런 불안한 상태를 장비 추가가 이루어질 때까지 불안하게 쳐다보고 있어야 한다는 단점이 있습니다. 게다가 Rebalance 에 대한 이해 없이 그냥 강제로 서버를 빼고 그냥 추가만 해버리면 데이터가 유실되는 끔찍한 사태를 겪을 수 있습니다.

그러므로 많은 노하우가 축적된 RDBMS 보다는 좀 더 신중하게 접근할 필요가 있으며 단순히 인터넷의 문서(Couchbase 공식 홈페이지에는 자세한 영문 문서가 제공됩니다)만 보고 작업했다가 실제 서비스 도중 재앙을 맞딱드릴 수 있으니 정식 지원 서비스에 가입을 하거나 정식 지원 서비스를 받은 적이 있는 엔지니어를 고용해서 서비스 하는 것을 권하고 싶습니다.



또다른 사용기는 다음 글에...

댓글 없음:

댓글 쓰기