MongoDB란?
MongoDB란?
MongoDB는 NoSQL 데이터베이스로, JSON 형태의 데이터를 저장하는 도큐먼트 지향 데이터베이스 입니다. 웹 애플리케이션과 인터넷을 기반을 위해 설계된 데이터베이스입니다. 데이터 모델과 지속성 전략은 높은 읽기/쓰기 효율과 Failover를 통한 확장의 용이성을 염두에 두고 만들어 졌습니다.
많은 개발자들이 MongoDB를 사용하는 이유는 확장성 보다는 직관적인 데이터 모델 때문입니다. 데이터 값은 Row 값이 아닌 document에 저장합니다. 그럼 도큐먼트는 무엇일까요?
MongoDB의 도큐먼트 형식은 임의의 데이터 구조를 저장하는 스키마로 잘 알려진 JSON에 기반합니다. JSON은 JavaScript Object Notation의 약자입니다. MongoDB는 RDBMS들이 테이블 형태로 데이터를 저장하는데 방식과 달리 웹서버와 통신할 때 자주 쓰이는 JSON(JavaScript Object Nation) 형식의 문서를 이용합니다. JavaScript Object Notation(JSON)은 XML과 함께 현대 웹에서 사용되는 데이터 교환의 기본 형식입니다. JSON은 숫자, 문자열 및 부울 값과 같은 모든 기본 데이터 유형을 지원하며 배열과 해시도 지원합니다. JSON의 구조는 키(Key)와 키에 대한 값(value)로 이루어져 있고, 중첩에 제한이 없습니다. 도큐먼트 기반의 데이터 모델은 풍부하고 계층적인 구조의 데이터를 표현할 수 있습니다. 따라서 RDBMS에서 필요한 여러 테이블 간의 복잡한 조인 연산이 없어도 됩니다.
SQL을 지원하지 않기 때문에 조인(Join) 개념이 없고, 스키마가 유동적입니다. 여기서 유동적이라는 말은 MongoDB에서 저장하는 데이터 단위가 ‘도큐먼트’라는 것을 의미하며, 이는 RDBMS에서 행 단위의 레코드라고 할 수 있습니다. 따라서 MongoDB의 도큐먼트 속성은 SQL처럼 정형화 되어 있지 않고, 가변적이기 때문에 모든 문서 형태가 비정형 데이터를 저장하고 처리하는데 적합합니다. 객체지향 언어들을 사용해 프로그래밍 할때 프로그래밍 언어에서 정의한 객체가 그대로 저장되므로 객체 맵퍼(mapper)의 복잡성이 사라집니다.
MongoDB는 BSON(Binary JSON)이라고 하는 Binary 인코딩 형식으로 JSON 문서를 저장합니다. BSON은 JSON 모델을 확장하여 추가 데이터 유형, 순서 필드를 제공하고 서로 다른 언어 내에서 인코딩 및 디코딩에 효율적입니다. BSON의 사이즈 제한은 최대 크기인 16MB를 넘을수 없습니다.
RDBMS | MongoDB |
Database | Database |
Table | Collection |
Index | Index |
Row | Document |
Join | Embedding & Linking |
관계형 모델에서는 테이블이라는 틀 때문에 새로운 테이블을 생성하고 두 테이블 사이의 관계를 컬럼에 저장해서 데이터를 표시할 수 밖에 없습니다. 하지만 MongoDB 모델에서는 단순히 값을 배열(array)로 바꾸는 작업만으로 구조를 간단히 바꿀수 있습니다.
MongoDB의 가장 큰 장점은 복제(Replicate)와 샤딩(Sharding)을 기본적으로 제공하고 있다는 점입니다. 복제는 장애 대비 및 데이터의 보존을 위해, 샤딩은 정보를 분산하여 I/O속도를 높이는데 사용할 수 있습니다.
기존의 RDBMS들에 비해 스키마 변경이 자유롭기 때문에, 미래에 대한 예측이 어렵거나 최종적으로 결정되지 않은 모델의 경우 MongoDB를 도입이 유용합니다. 또 분산 컴퓨터 환경이 필요한 경우 MongoDB는 좋은 선택이 될수도 있습니다. Schemaless 환경이라는 것은 RDBMS에 비해 비교적 스키마에 대한 제한에서 자유롭다는 뜻이지 스키마가 없는 환경이 아닙니다. 따라서 MongoDB 역시 Flexible 스키마에 대한 적절한 모델링이 필요하고, DBA는 Schema validate, modeling에 대한 스킬을 필요로 하게 됩니다.
MongoDB의 주요 특징
- 신뢰성 (Reliability)
- 확장성 (Sacalability)
- 유연성 (Flexibility)
- 인덱스 지원 (Index Support)
신뢰성(Reliability)이란 하나의 서버에 장애가 발생한 경우에도 서비스는 계속 동작할 수 있는 고가용성 환경을 MongoDB에서 자체적으로 지원한다는 것 입니다.
확장성(Sacalability)은 데이터와 트래픽 증가에 따라 수평확장이 가능합니다. 샤딩을 기본적으로 제공하고, 온라인 중에 노드를 추가하고 데이터에 대한 리발란싱이 가능힙니다.
유연성(Flexibility)은 여러가지 형태의 데이터를 손쉽게 저장할 수 있음을 나타내며 개발 과정중에 스키마 변경이 필요한 경우 쉽게 대처가 가능합니다.
MongoDB는 RDBMS 같은 인덱스 지원(Index Support)을 하기 때문에 다양한 조건으로 빠른 데이터 검색이 가능합니다. Full TEXT Index, TTL index, 공간 Index 등 다양한 인덱스를 지원합니다.
스키마가 없는 모델의 장점
데이터베이스가 아닌 애플리케이션이 데이터 구조를 정합니다. 데이터 구조가 빈번히 변경되는 구조에서 초기단계에 개발 초기속도를 단축시켜 줍니다. 스키마가 없는 데이터 모델을 통해 가변적인 속성을 갖는 데이터를 표현할 수 있습니다.
애드혹 쿼리 (ad hoc query)
많은 NoSQL 데이터베이스가 간단하고 확장성이 높은 모델을 채택하고 있는 대신 동적 질의를 제공하지 않습니다. 예를 들면 키-값 타입의 저장 시스템은 하나의 키-값으로만 질의가 가능합니다. 일반적으로 RDBMS에서는 기본적으로 제공하는 기능인데, MongoDB의 설계 목적중에 하나는 RDBMS에서 필수적인 풍부한 쿼리 기능을 NoSQL에서도 사용할 수 있게 하는것 입니다. Post와 Comments에 관련된 예를 들어 추천수가 10이상의 ‘politics’라는 용어로 된 태그된 모든 포스트를 찾으려할 때, SQL과 MongoDB의 쿼리의 차이를 아래와 같이 확인할 수 있습니다.
SQL
SELECT * FROM posts INNER JOIN posts_tags ON posts.id = posts_tags.post_id INNER JOIN tags ON posts_tags.tag_id == tags.id WHERE tags.text = 'politics' AND posts.vote_count > 10;
MongoDB
db.posts.find({'tags': 'politics', 'vote_count': {'$gt: 10}});
SQL 쿼리는 포스트 태그를 서로 다른 테이블에 저장함으로써 엄격하게 정규화된 모델에 의존하는 반면, MongoDB의 쿼리는 태그가 각 도큐먼트에 포함되어 있다고 가정합니다. 하지만 두 쿼리 모두 여러 개의 속성을 임의로 조합하여 질의할 수 있는 능력을 보여줍니다.
인덱스
MongoDB에서 인덱스는 B-Tree로 구현되어 있습니다. 그래서 인덱스 범위를 스캔하거나 정렬하는 것과 같이 다양한 쿼리에 대해 최적화되어 있습니다. 다른 NoSQL 데이터베이스의 경우 키-값 저장소로 사용되는데 세컨더리 인덱스를 허용하지 않는데 반해 MongoDB에서는 세컨더리 인덱스를 통해 더 넓은 범위의 쿼리를 최적화할 수 있습니다. MongoDB는 한 컬렉션에 64개까지 세컨더리 인덱스를 만들수 있습니다. 오름차순, 내림차순, Unique, 복합키(compound-key), 해시, 텍스트, 공간인덱스 같은 모든 인덱스를 사용가능 합니다.
복제 세트 (replica set)
MongoDB는 자체적으로 복제기능을 갖추고 있고, 장애에 대비해 데이터를 여러대의 서버에 분산하며, 자동화된 failover 시스템을 제공합니다. 또한, 복제 세트를 통해 읽기 작업을 분산할 수도 있습니다.
속도와 내구성
많은 RDBMS가 캐시와 디스크를 조합하며, 메모리에 우선적으로 쓰기 작업이나 데이터를 읽어와서 처리하고, 메모리에서 완료된 작업만은 디스크에서 처리하는 방식을 사용합니다. MongoDB의 경우 쓰기 시맨틱스(Write semantics)와 저널링(journaling)을 통해 구현이 되어 있습니다.
확장
MongoDB는 샤딩을 통한 확장을 지원합니다.
트랜잭션
기존의 NoSQL 데이터베이스들은 트랜잭션을 지원하지 않았지만, MongoDB는 4버전 부터 Replication Set 대한 트랜잭션을 지원하기 시작했고, 4.2부터는 RDBMS 같은 트랜잭션 기능을 지원하기 시작했습니다. 4.2이상의 버전에서 클러스터 샤드간의 ACID 트랜잭션을 지원하며, RDBMS의 트랜잭션과 동일하게 사용하는 것이 목적으로 개발되었습니다. MongoDB에도 트랜잭션을 위해 3버전대에서 세션이라는 항목이 추가 되었고, 꾸준히 4.2까지 버전업을 하면서 트랜잭션에 대한 준비를 많이 해왔습니다. 트랜잭션 기능은 4.2이상 버전의 MongoDB 드라이버를 사용하여야 하며, 기본 DML의 타임아웃은 60초 입니다. 이것은 파라미터 값을 변경해 바꿀수 있습니다. TX경합이 발생하는 경우 60초까지 기다렸다가 타임아웃 혹은 처리를 하게 됩니다. 하나의 트랜잭션 내에서 많은 도큐먼트를 변경하는 작업은 권장하지 않으며, 이런 작업의 경우 배치형태의 처리를 권장합니다.
트랜잭션에 대해서는 나중에 자세히 알아보도록 하고, 오늘은 MongoDB도 트랜잭션을 지원한다 라는 정도만 알고 넘어가려고 합니다.
MongoDB를 사용하는 이유
MongoDB는 위에서 살펴본것 처럼 RDBMS와 NoSQL의 장점만을 모아 설계되었습니다. 따라서 MongoDB는 웹 애플리케이션, 분석과 로깅 애플리케이션, Cache를 필요로하는 하는 애플리케이션에서 1차 저장 시스템으로 적합합니다. 또한, 스키마가 없는 데이터를 저장하기가 유용함으로 미리 구조를 알기 힘든 데이터를 저장하는데 유용합니다.
다른 데이터베이스와 비교
예 | 데이터 모델 | 용례 | |
간단한 키-값 저장 시스템 | Memcached, Redis | 키-값,
멤캐시디는 이진 blob |
캐싱, 웹 ops |
정교한 키-값 저장 시스템 | 카산드라, 볼드모트 프로젝트, Riak 등 | 카산드라는 칼럼으로 부르는 키-값을 사용.
볼드모트는 이진 blob을 사용. |
고효율 verticals(액티비티 피드, 메시지 큐)
캐싱. 웹 ops |
RDBMS | 오라클, MySQL, MariaDB, PostgreSQL 등 | 테이블 | 트랜잭션이 필요한 시스템 또는 SQL.
정규화된 데이터 모델. |
정교한 키-값 저장 시스템
아마존의 다이나모(Dynamo)가 대표적인데 다이나모의 가장 큰 목표는 네트워크 장애나 데이터 센터 장애 등 다양한 장애가 발생했을때에도 지속적인 서비스를 위한 데이터저장 시스템이었습니다. 여러개의 노드에 걸쳐 자동으로 복제가 되고 모든 노드에서 읽기와 쓰기 작업을 할 수 있으며, 같은 데이터에 대해 여러 노드에 쓰기 연산을 허용할 때 발생할 수 있는 충돌을 해결하는 방법을 제공합니다. 다수의 노드를 마스터가 없는 동등한 한의 시스템으로 이해하면 쉽습니다. 다이나모에서 처음 시작된 아이디어지만, HBase나 Riak, 카산드라 같은 NoSQL에서도 비슷한 방식으로 시스템이 구성됩니다. 대부분의 NoSQL은 정말 많은 양의 데이터를 관리하기 위해 개발되었습니다. 마스터가 없는 환경에서는 현재 읽은 데이터가 반드시 최신 데이터는 아닌 다소 느슨한 일관성을 가지고 있습니다.
RDBMS
오라클이 대표적이며 최근 MySQL과 MariaDB, PostgreSQL 까지 테이블 단위의 데이터베이스입니다. 일반적으로 우리가 흔히 알고 있는 데이터베이스이기 때문에 설명을 생략합니다.
Document DB
MongoDB와 CouchDB가 있으며, CouchDB는 JSON을 단순 텍스트로 저장합니다. CouchDB도 세컨더리 인덱스를 지원하지만, 인덱스가 맵리듀스 함수를 작성해서 정의됩니다. 샤딩은 지원하지 않고 각각의 노드에 동일한 복제 노드만 구성됩니다.
참고 자료
도서 : 맛있는 몽고DB
도서: Real MongoDB
도서: 오픈소스 몽고DB
도서: MongoDB in Action
MongoDB Manual: https://docs.mongodb.com/manual/
최신 댓글