2014년 4월 10일 목요일

Couchbase 도입기 - 1

Couchbase 는 NoSQL 제품 중 하나입니다.

Couchbase 는 상용이고, 커뮤니티 버젼이라는 무료 버젼도 제공하고 있습니다.
MySQL 등의 커뮤티니 버젼이 동일 버젼에 기능에 제약이 있거나 상용 버젼에 일부 코드가 튜닝되어 나온다는 등의 기능 차이가 있다면, Couchbase 는 (아직까지는)마이너 버젼 1 개 차이의 이전 버젼을 배포하는 것이 특징인 것 같습니다. 예를 들면, 2.2 버젼이 Enterprise 버젼(상용)의 최신 버젼이라면 Community 버젼은 2.1 을 제공하는 형태입니다. 이 글을 쓰는 지금은 2.5 가 최신 버젼이고, 2.2 에서 2.5 로 바로 건너띈 바람에 Community 버젼은 2.2 가 제공되고 있습니다.

Couchbase 는 Linux 배포판 중 Redhat, Debian 계열의 패키지인 rpm 와 deb 을 지원하고 있으며, 각각 yum 와 apt-get 을 통해 네트워크 설치를 지원합니다. 이런 패키지 관리자를 통해 설치할 경우 의존성이 있는 패키지를 동시에 설치해주므로 좀 더 편리한 설치가 가능합니다.


Couchbase 는 CouchDB 와 Memcached 을 섞어놓은 솔루션입니다. 그러므로, Couchbase 의 자료 뿐만 아니라 CouchDB 의 map/reduce 에 관한 자료나 Memcached 에 관한 자료를 참고하시면 도움이 많이 됩니다.





제가 Couchbase 을 도입하게 된 이유는 속도와 자동화된 기능 때문입니다.

게임 회사에 입사해서 게임 서버를 Java 로 개발하게 되었는데, 무료 위주의 솔루션으로 구축하자는 회사의 방침에 따라 정보 저장은 RDBMS 인 MySQL, 정확히는 MariaDB 를 사용하도록 일찌감치 낙점되었습니다. 그리고 Clustering 의 경우 MariaDB 에서 지원하는 Galera Cluster 을 쓰는 것으로 결정하였습니다. MySQL 의 NDB 클러스나 MMM, Master-Master Circular Replication 보다 사용하기 용이하고 완벽한 동기식 Cluster 라는 장점 때문이었습니다.
하지만, 이건 저의 착각이었습니다. Galera Cluster 의 경우 매우 좋은 성능을 보여주는 Cluster 임에는 분명했지만, Write 가 대량으로 발생하는 시스템에서는 그다지 좋은 성능을 보여주지 못하는 문제가 있었습니다. 한 서버에 Write 을 하게 되면 다른 모든 서버에 bin-log 을 복제하여 이를 적용하게 되고, 적용이 완료된 상태가 되어야 Write 작업이 마무리되게 되는데, 이 시간이 처리 속도의 관점에서 그리 빠르지 않다는 것이었습니다. 그래서 입력하는 서버에서 DeadLock 이 발생하는 것이 아니라 전파하는 속도 사이에 다른 요청이 들어와서 DeadLock 이 발생하는 문제가 생겼습니다. 이를 해결하기 위해서는 한 개의 MariaDB 에만 Write 을 하도록 하고, 나머지 서버에서는 Read-Only 상태로 사용해야 한다는 제약이 있다는 것을 알게 되었습니다.
일반적인 웹사이트에서는 Read 가 압도적으로 많기 때문에 이러한 구성이 문제가 없으나, 게임 서버는 그렇지 않습니다. 거의 1:1 의 Write/Read 가 발생하는 것이 정상적인 모습이기 때문입니다. 특히나 Log 형태의 데이터가 많아서 어떨 때에는 Write 비율이 더 많습니다.

그리고, KT UCloudBiz 을 이용하는데, KT UCloudbiz 에서만 제공한다고 알고 있는 "SSD" 서버의 성능은 압도적으로 좋은 퍼포먼스를 보여줍니다만, 그렇다고 해서 하루 수 천만 라인의 Write 가 이루어지는 게임 서버의 요구를 만족할 수는 없었습니다. SSD 서버의 경우 저의 테스트로는 초당 1만 건 정도의 트랜젝션을 처리할 수 있었습니다. 병렬로 늘리는(Scale Out) 작업이 불가능하다록 위에서 언급했기 때문에 프로그래밍 적으로 샤딩(Sharding)을 하지 않고서는 서비스를 할 수 없다는 결론이 나왔습니다.

그래서 최초로 생각한 것은 Redis 였습니다.

Redis 는 무료이며, Key-Value 방식의 간단한 구조를 가지고 있지만 매우 빠른 속도를 자랑하는 NoSQL 솔루션입니다. 단순 증가 필드도 지원해서 MySQL 계열에서 가지는 문제 중 하나인 auto increment(auto increment 필드로 지정해두면, 해당 테이블 추가시 Table Lock 이 발생한다!!!)를 해결할 수도 있었습니다.
하지만, 메모리를 이용하는 방식이라 데이터 유실에 대한 위험이 존재했고, 이를 보안하기 위한 하드디스크를 이용하게 될 경우 속도가 비극(?)적으로 느려진다는 보고가 보였습니다. 굉장히 꺼려지는 부분이었습니다.
거기다, 더 큰 문제가 발생했습니다. Clustering 이 원하는 형태대로 지원이 안되는 것이었습니다. 여러 개의 Redis 을 설치한 뒤 Sentinel 이라는 자체 솔루션을 이용해 Cluster 을 구성할 수 있었지만 수동으로 정상적인 서버의 위치를 알려줘야 했고, 이를 해결하기 위한 githup 의 몇몇 솔루션을 적용해봤으나 서비스 중단 시간이 수십초 씩 걸리는 문제가 발생했습니다.
게임에서 이런 중단 시간은 용납이 안됩니다.



그래서 찾아낸 것이 Couchbase 였습니다. 적극 권장하는 솔루션입니다...만...고생도 좀 했습니다.



이 다음 이야기는 다음 글에서 계속합니다...

댓글 2개: