[발 번역] MongoDB Best Practices

해당 글은 http://www.engineyard.com/blog/2011/mongodb-best-practices/ 의 MongoDB Best Practice 를 발 번역한 글입니다. 오역에 주의하세요.

MongoDB Best Practices

안녕하세요. Engine Yard Data Team 입니다. 지난번에 블로깅한 이후로 무슨 일이 있었는지 알려드리길 바랍니다.

데이터 팀은 올해 초에 만들어진 후, 첫번째 작업은 MongoDB stack을 확장하는 것이었습니다. 그러나, 관계형 DB의 업데이트 없이  NoSQL 저장소를 추가한다면, 고객에게 몹쓸짓을 하게 된다는 것을 느꼈습니다. 그래서 MongoDB 개발을 멈추고 MySQL과 PostgreSQL 의 업데이트 하기로 결정했습니다.  최근에 MySQL 5.5 베타가 출시되었고 PostgresSQL 9.1 베타는 곧 나올 것입니다. 그리고 2012년 1분기쯤 GA버전을 출시할 계획입니다.

이제 MongoDB에 더 초점을 맞추고, 몇몇 고객의 MongoDB 사용을 돕고 있습니다.  이 작업 동안에 다양한 잠재된 문제점을 발견했습니다. 이번 기회에 MongoDB를 위한 Engine Yard의 best practices를 공유하고 싶습니다.
MongoDB를 개별적으로 설치했다면, 해당 글에 맞춰서 설치를 체크하시길 바랍니다. 필요하다면, 설정을 바꾸길 권장합니다. 만약 도움이 필요하다면, Professional Services 조직에 도움을 요청하시길 바랍니다.

General NoSQL best practices

NoSQL을 선택하는 방법에 대한 많은 문서들이 있습니다. Read/Write 성능, 안정성, 데이터 일관성, 네트웍 응답속도 등 여러 특징들을, 어플리케이션에서 요구하는 것을 고민해서 잘 선택해야 합니다. 해당 문제에 대해서  Nathan Hurst in가  “Visual Guide to NoSQL Systems” 에 잘 요약해두었습니다.

올바른 NoSQL을 선택하는 것은 이 문서의 범위를 넘어가므로, 직접 조사하시기 바랍니다.  모든 상황에 맞는 하나의 솔루션을 없을 것입니다. 해당 문서도 MongoDB가 요구하는 어플리케이션에 적합하다고 가정하고 넘어갑니다. Engine Yard 에서 추천하는 부분은 다음과 같습니다.

미친듯이 테스트 하라 – Test exhaustively

어플리케이션이 실제 서비스 하는 시스템에서 받을 수 있는 트래픽 상황에 맞추어서 테스트 해야 합니다. 실서비스에는 성능 병목 현상이 발견되거나,아키텍처 디자인에서에서 문제가 발생해도, 테스트 시스템에서는 재현되지 않습니다. 쿼리를 실서비스와 비슷하게 테스트하고, 측정값들을 항상 수집 해야합니다.( 역자 주: 실제로, NoSQL 서비스의 벤치마크만 믿고 시작하면, 문제가 발생할 여지가 많습니다. 이것은, 자신의 상황에 맞춰서 테스트를 해보지 않아서 그렇습니다. – 이렇게 테스트를 해도 실제 환경에서는 좀 더 문제가 발생할 수 있습니다. – 예를 들어, 하루 정도 테스트 할 때는 문제가 없었는데, 일주일 이상 실 서비스에 돌려보니, 메모리 부족으로 GC가 발동해서, 서비스가 확 떨어지는 문제가 나올 수도 있고, 테스트 시에는 10개 정도의 필드만 사용했는데, 실 서비스는 100개 이상이라, 속도 차이가 현저히 발생할 수 있습니다. )

RDBMS를 그대로 대체할 수 있다고 가정하지 말라 – Don’t assume that what worked for your RDBMS will translate

 SQL 데이터베이스에서 도는 작업은 뭐든지,  MongoDB에서 동작하지 않을 수 있습니다.  그래서 기대는 현실적인지, 실제 데이터베이스의 기능을 적용할 수 있을지 확인해야 합니다. 좀 더 좋은 성능을 위해서, documents(역자주: MongoDB는 Document 기반), 와 Query를 10gen에서 추천한 방법을 따르는게 좋습니다.  비 관계형 저장소로 넘어가기 위해서 어플리케이션이 다시 설계되어야할 필요가 있다는 것을 이해해야합니다.  NoSQL로 의 이전을 위해 더 정보가 필요하다면  “The cost of Migration” 를 일기 바랍니다.(역자 주: 보통 가장 많이 하는 실수가 기존의 RDBMS 의 데이터 모델을 NoSQL로 그대로 넘어가길 원한다는 것입니다. 먼저 자신의 데이터가 NoSQL에 적합한가를 고민하는 것이 최우선입니다. 그리고, 그게 아니라면, 그냥 RDBMS를 써야 합니다. 참고로, 어떤 NoSQL도 현재 중요한 데이터를 혼자 저장하는데 사용하라고 추천하는 곳은 없습니다. 모든 곳에서 중요한 데이터는 넣지 마시오라고 가이드합니다. 여기서 중요한 데이터는, 중요한데, 새로 만들 수 없는 데이터를 의미합니다. 만약 쉽게 다시 만들 수 있는 데이터라면, 날라가도 다시 만들 수 있으니 큰 문제가 없을 수 있습니다.)

데이터에 대한 일관성과 안전성이 필요한지 고민하라 – Think about the consistency and durability needs of your data.

데이터 일관성과 안전성이 필요한지 고민해야 합니다. 이것은 강요할 수 없습니다. 직접 MongoDB에서 제공하는 리플리케이션을 통한 안전성을 판단해야 합니다. 실 서비스 동안 MongoDB 하나만 사용하는 것을 절대로 추천하지 않습니다. 왜 그래야 하는지 확인하시기 바랍니다.

EBS Volumes에서 무엇을 기대할 수 있는지 이해하십시오 – Understand what to expect from EBS volumes

만약 Engine Yard Cloud(AWS EC2) 고객이라면  아마존 Elastic Block Storage(EBS)의 성능이 항상 같지 않다는 것을 알아야 합니다. 어플리케이션 벤치마킹을 하거나, 데이터를 구성하는 동안에, 시간에 따른 지표를 수집해야 합니다.  Engine Yard는 고객이 이런 불편함이 없도록 관리합니다.

MongoDB Best Practices

MongoDB를 우리의 Stack에 릴리즈 하는데 따라야 하는 지침은 다음과 같습니다.

항상 Replica Sets을 사용하라 – Always use replica sets

Replica Sets은 장애시 자동 FailOver를 통해서 HA(고 가용성)를 제공합니다. Primary 노드에 장애가 난다면, Secondary 노드가 Primary 로 선출됩고, 서비스는 계속 동작합니다. 실서비스 환경에서 Replicate 하지 않는 MongoDB는 Engine Yard에서는 서포팅하지 않습니다. Mongo 디비를 Replication 하는 비용이 너무 비싼것 같다면 Hosted 솔루션을 고려해보시기 바랍니다. Engine Yard는 MongoHQ 와 MongoLabs와 파트너쉽을 가지고 있습니다.  더 많은 정보가 필요하다면 Partners page 를 보시기 바랍니다.

최신 버전을 유지하라 – Keep current with versions

최신 버전을 MongoDB를 유지하길 바랍니다. 10gen 에서는 매 릴리즈마다, 클러스터를 좀 더 안정적으로 돌 수 있게 하는 많은 패치를 냅니다. Version 2.0.x 의 경우 클러스터를 쉽게 증가시킬 수 있는 중요한 성능, 동시성 증대, 인덱스 변경, 버그 픽스, Compaction 커맨드등을 포함하고 있습니다. 만약 1.6.3을 사용한다면, 가능한 업그레이드 하길 바랍니다.( 역자 주: 지속적으로 발전하는 NoSQL등의 경우, bug fix를 보는 것이 상당히 중요합니다. Mysql등의 오래된 패키지는 새 버전이 나오면 검증을 오래하고 적용하게 되지만, MongoDB의 경우도 2.0.0에서 Consistency 문제가 있어서 긴급히 2.0.1이 발표되었습니다.)

MongoDB를 32bit에서 사용하지 말라 – Don’t run MongoDB on 32-bit systems

32bit 시스템에서는 MongoDB는 2.5GB 의 데이터 밖에 사용할 수 없습니다. Storage Engine이 성능상의 이유로 Memory-Mapped Filed을 사용하고, 이로 인해 메모리 어드레싱이 2.5 까지 밖에 사용할 수 없기 때문입니다. Engine Yard Cloud 에서는 기본적으로 Large Instance를 이용합니다. 그리고 64bit MongoDB 만 지원합니다.( 역자 주: 모든 NoSQL이 64bit에 풍부한 메모리를 권장합니다. 이 이유는 대부분 빠른 속도를 위해서 많은 메모리를 사용하고, 데이터 량이 예전과 다르게 많기 때문입니다.  특히 MongoDB의 경우 index가 메모리 사이즈보다 커지면, 속도에 큰 저해가 오기 때문에, 메모리를 많이 다시는 게 좋습니다. 포스퀘어 같은 경우는 65G가 메모리를  MongoDB 서버 한대당 사용한다고 합니다. )

기본적으로 Journaling을 사용하라 – Turn journaling on by default

 MongoDB는  장애 복구나 노드의 안전성을 위해서 Write-Ahread 저널링을 지원합니다. 우리는 저널링을 기본적으로 사용하기를 강력하게 추천합니다.(역자 주: 현재 MongoDB 개발 트리는 기본적으로 저널링이 enable 되어있다고 합니다.)

데이터 파일의 위치를 확인하라  – Mind the location of your data files

MongoDB 데이터 파일이 영구저장되는 볼륨에 있는지 확인해야합니다.(예: /data/mongodb) 임시 드라이브에도 저장할 수 있지만, 클러스터 아키텍처에 영향을 주므로 매우 조심해야 합니다. MongoDB 데이터를 EBS에 저장하는 것을 추천합니다.(역자 주: 개인적으로 DB내용을 임시 노드에 올려둔다는 것은 조금 이해가 안갑니다. 다만 주의할 것은 /tmp 노드에 기본적으로 저장되는 것에 주의해야 합니다. 간단하게 mysql의 경우 /tmp/mysql.sock 이 기본 통신 채널인데 /tmp를 정기적으로 삭제하는 정책이 있을 경우, 서비스에 문제를 일으킬 수 있습니다. NoSQL 을 사용하면서 데이터가 이상해라고 말하는 케이스 중에, 이렇게 /tmp를 NoSQL 정보의 임시 저장소로 만들어두고, 해당 영역이 지워지거나 꽉 차서 발생하는 케이스가 많습니다.)

Working Set은 메모리 사이즈에 적합하게 유지하라 – Your working set should fit in memory

 Working Set(Index)을 메모리에 두는 것은 클러스의 영향을 미치는 매우 중요한 요소입니다. Page Fault 가 증가하는 것을 알면, 가용 메모리보다 Working Set 의 사이즈가 커진다는 것을 알 수 있는 알 수 있는 매우 좋은 기회입니다.  가용 메모리보다 Working Set 데이터가 증가하면 두 가지 방법이 있습니다. MongoDB의 메모리 사이즈를 증가시키거나, 샤딩을 하는 것입니다. MongoDB의 메모리 사이즈를 증가시키는 것을 먼저 추천합니다. ( 역자 주: 다만 데이터 양이 너무 많아지면, 결국 scale up은 한계가 있으므로, 샤딩으로 가야합니다. )

엄청 많이 사용한다면 Scale Up을 하라 – Scale up if your metrics show heavy use

장비의 load가 65%를 넘는다면, Scaling up을 고려해야 합니다. 평균적으로 동작할 때 load가 , 일관성있게 해당 수치 이하여야 합니다.  복구나, 수직 Scaling 상황에도 영향을 줍니다. instance size를 늘려야 할 필요가 있다면, AWS는 Large, Extra Large, high Memory 4XL 순서로 업그레이드를  추천합니다.  큰 EBS 볼륨에서도 latency가 적습니다.

샤딩에 주의하라 – Be careful when sharding

샤딩을 적용하는 것은 어플리케이션의 액세스 패턴에 대한 깊은 이해가 필요합니다. MongoDB가 어떻게 샤딩을 하고 정말로 샤딩이 필요한지에 대해서 시간을 드려서 고민하시기 바랍니다. 그리고 성능에 영향을 주는 좋은 샤딩 키를 선택하는 것도 중요합니다.(selecting a good sharding key) ( 역자 주: 샤딩의 경우 샤딩키를 제외하고는, Unique 속성을 줄 수 없습니다. 복합 샤딩키는 가능합니다.)

Config 서버는 클러스터 상태에 매우 중요합니다. 실서비스의 샤딩 환경에서는 3 대의 Config 서버가 필요합니다. 자주 Config 서버의 데이터를 백업하고,  그것을 확인하고, 절대로 Config 서버의 데이터를 지우면 안됩니다. 가능하면 /etc/hosts 파일에 서버 이름을 저장해두고 사용하길 바랍니다.( 클러스터를 좀 더 탄력적으로 만들 수 있습니다.)

Config 서버는 경량 프로세스이지만, 역시 64bit 장비에서 동작해야 합니다. 3개의 Config 서버를 한 장비에 몰아넣으면 안됩니다. 만약, 샤드된 설치를 고려한다면 Engine Yard Professional Services 에 컨설팅 스케줄을 잡으실 수 있습니다.

 그래픽적으로 모니터링 하기 위해서 MongoMMS를 사용하라 – Use Mongo MMS to graphically monitor your service

만약 이미 Mongo MMS 를 사용해본 적이 없다면, 10gen 에서 열정적으로 개발하고 있는 제품으로, 클러스터의 상태를 체크해서 최고의 방법으로 표시해 줄것입니다.

 MongoDB resource를 살펴라 – Keep up with MongoDB resources

빨리 바뀌므로, 정보를 항상 최신으로 유지하라. 다음 사이트에서 정보를 찾을 수 있습니다.

뭔가 더 듣고 싶나요? 피드백을 주세요 – Want to hear more? Give us feedback!

피드백은  빠른 릴리즈 프로세스, 블로그 포스팅 계획, 로드맵 우선 순위등 많은 곳에 이용됩니다. 어떤 알파/베타 릴리즈를 시도하는지, 어떤 질문이라도 해주시기 바랍니다. 우리의 데이터베이스가 계속 최적화되고 계속 발전하기를 바랍니다.
(역자 주: 여기에 조금만 더 추가하자면, MongoDB의 경우 보안 기능이 기본적으로 disable 되어 있기 때문에,  이걸 키고 사용하는게 좋습니다. http://www.mongodb.org/display/DOCS/Security+and+Authentication 여기서 보실 수 있습니다.  MongoDB의 소스를 보면 MONGO_SSL을 사용할 수 있도록 들어가 있는 것 같습니다. 전체 데이터에 대한 SSL 지원인지는 좀 더 봐야겠네요 ^^)