MongoDB 쓰지 마세요: 아니 그냥 써도 돼요

MongoDB 쓰지 마세요: 아니 그냥 써도 돼요

D
dongAuthor
6 min read

한때 개발 커뮤니티에서 "MongoDB 쓰지 마세요"라는 말이 유행했던 적이 있습니다. 스키마가 없다는 이유로, 트랜잭션 지원이 부족하다는 이유로 많은 개발자들이 MongoDB를 기피했죠. 하지만 2024년 현재, 이런 편견들은 대부분 과거의 이야기가 되었습니다.

Why You Should Never Use MongoDB

MongoDB는 지속적인 발전을 통해 엔터프라이즈급 데이터베이스로 성장했고, Stripe처럼 연간 1조 달러의 결제를 처리하는 회사에서도 핵심 인프라로 사용하고 있습니다. 이 글에서는 MongoDB가 왜 좋은 선택인지, 그리고 실제 대규모 서비스에서 어떻게 활용되고 있는지 살펴보겠습니다.

“MongoDB 쓰지 마세요” 이제는 다릅니다

과거 MongoDB에 대한 비판은 대부분 초기 버전의 한계에서 비롯되었습니다. 스키마 검증 부족, ACID 트랜잭션 미지원, 데이터 일관성 문제 등이 주요 쟁점이었죠. 하지만 현재 MongoDB는 이런 문제들을 대부분 해결했습니다.

스키마 검증 지원: MongoDB는 이제 스키마 검증 기능을 제공합니다. JSON 스키마를 통해 데이터 구조를 강제할 수 있어, 필요에 따라 RDBMS와 유사한 제약 조건을 설정할 수 있습니다.

트랜잭션 지원: 4.2 버전부터 완전한 ACID 트랜잭션을 지원합니다. 물론 대규모 트랜잭션은 성능 저하를 일으킬 수 있지만, 이는 다른 데이터베이스도 마찬가지입니다.

고가용성과 일관성: Raft 알고리즘 기반의 자동 장애 조치를 통해 약 1초 내에 복구가 가능하며, read/write concern 설정을 통해 데이터 일관성과 트래픽 분산을 효율적으로 관리할 수 있습니다.

이제 MongoDB는 “빠르게 프로토타입을 만들 때만” 사용하는 데이터베이스가 아닙니다. 엔터프라이즈 환경에서도 충분히 안정적이고 확장 가능한 솔루션이 되었어요.

How Stripe’s document databases supported 99.999% uptime with zero-downtime data migrations

TLA+로 검증 받은 MongoDB

TLA+(Temporal Logic of Actions Plus)는 분산 시스템의 알고리즘을 수학적으로 명세하고 검증하기 위한 언어입니다. 간단히 말해서, 복잡한 시스템이 의도한 대로 동작하는지 미리 검증할 수 있게 해주는 도구죠.

MongoDB는 분산 알고리즘을 설계할 때 TLA+를 사용해서 시스템의 정확성을 보장합니다. 예를 들어, 여러 노드 간의 데이터 복제가 올바르게 이루어지는지, 장애 상황에서 데이터 일관성이 유지되는지 등을 TLA+로 모델링하고 검증합니다.

이는 MongoDB가 단순히 “빨리 만든” NoSQL 데이터베이스가 아니라, 수학적 증명을 통해 안정성을 보장하는 엔터프라이즈급 시스템임을 보여줍니다. TLA+를 통한 검증은 MongoDB의 분산 시스템 알고리즘이 이론적으로 신뢰할 수 있다는 것을 보여줍니다.

Conformance Checking at MongoDB: Testing That Our Code Matches Our TLA+ Specs

MongoDB의 핵심 기능들

Document-Oriented 구조

MongoDB는 데이터를 JSON 문서 형태로 저장합니다. 이는 내부적으로 BSON(Binary JSON)으로 변환되어 처리되죠. 이런 구조는 현대 웹 애플리케이션과 완벽하게 맞아떨어집니다.

// MongoDB 문서 예시
{
  "_id": ObjectId("507f1f77bcf86cd799439011"),
  "name": "김개발",
  "email": "kim@example.com",
  "skills": ["JavaScript", "React", "Node.js"],
  "projects": [
    {
      "name": "쇼핑몰 프로젝트",
      "status": "완료",
      "technologies": ["React", "MongoDB"]
    }
  ]
}

이런 중첩된 구조를 RDBMS에서 표현하려면 여러 테이블과 복잡한 JOIN이 필요하지만, MongoDB에서는 하나의 문서로 간단하게 처리할 수 있습니다.

유연한 스키마

스키마가 유연하다는 것은 "없다"는 뜻이 아닙니다. 필요에 따라 스키마를 강제할 수도 있고, 느슨하게 관리할 수도 있다는 의미예요. 예를 들어, 사용자 프로필 데이터에서 일부 사용자는 전화번호가 있고, 일부는 없을 수 있습니다. RDBMS에서는 NULL을 허용하거나 별도 테이블을 만들어야 하지만, MongoDB에서는 자연스럽게 처리됩니다.

확장성 (샤딩)

MongoDB의 샤딩은 정말 강력한 기능입니다. 데이터를 여러 서버에 자동으로 분산시켜 수평 확장을 가능하게 합니다. 샤드 클러스터는 다음 구성 요소들로 이루어져 있어요:

  • mongos: 쿼리를 적절한 샤드로 라우팅
  • config servers: 메타데이터 관리
  • shard nodes: 실제 데이터 저장

샤드 키를 통해 데이터를 분산시키며, 이를 통해 효율적인 쿼리 처리와 확장이 가능합니다. 하지만 샤드 키 선택이 잘못되면 성능 저하와 데이터 불균형을 초래할 수 있으니 신중하게 설계해야 해요.

다양한 인덱싱 기능

MongoDB는 B-Tree 기반의 단일 필드 인덱스부터 복합 키, 멀티키, 지리공간, 해시, 텍스트 인덱스까지 다양한 인덱싱을 지원합니다. 특히 지리공간 인덱스는 S2Geometry 라이브러리를 사용해서 위치 기반 데이터를 효율적으로 처리할 수 있어요.

// 지리공간 인덱스 생성 예시
db.places.createIndex({ "location": "2dsphere" })

// 반경 1km 내 검색
db.places.find({
  location: {
    $near: {
      $geometry: { type: "Point", coordinates: [127.0276, 37.4979] },
      $maxDistance: 1000
    }
  }
})

Stripe도 MongoDB를 적극적으로 사용합니다.

Stripe의 사례는 MongoDB가 엔터프라이즈 환경에서 얼마나 강력한지 보여주는 완벽한 예시입니다. 2023년 Stripe은 1조 달러의 결제를 처리하면서 99.999%의 가동률을 유지했습니다.

How Stripe’s document databases supported 99.999% uptime with zero-downtime data migrations

DocDB: MongoDB 기반의 커스텀 솔루션

Stripe은 MongoDB Community를 기반으로 DocDB라는 자체 데이터베이스 인프라를 구축했습니다. DocDB는 초당 500만 개 이상의 쿼리를 처리하며, Stripe의 모든 제품 애플리케이션을 지원합니다.

Stripe이 MongoDB를 선택한 이유는 다음과 같습니다:

  1. 문서 모델의 유연성: 복잡한 결제 데이터 구조를 자연스럽게 표현
  2. 대규모 실시간 데이터 처리 능력: 초당 수백만 건의 트랜잭션 처리
  3. 개발자 생산성 향상: RDBMS 대비 빠른 개발 속도

무중단 데이터 마이그레이션

Stripe의 가장 인상적인 성과 중 하나는 무중단 데이터 마이그레이션입니다. Data Movement Platform을 통해 서비스 중단 없이 데이터를 이동시킬 수 있어요. 이 시스템은 다음과 같은 단계로 작동합니다:

  1. 마이그레이션 등록: 청크 메타데이터 서비스에 마이그레이션 의도 등록
  2. 대량 데이터 가져오기: 스냅샷을 이용한 최적화된 데이터 로딩 (10배 성능 향상)
  3. 비동기 복제: Kafka와 Amazon S3를 활용한 실시간 동기화
  4. 정확성 검사: 데이터 완전성과 정확성 검증
  5. 트래픽 전환: 2초 내에 완료되는 무중단 전환

이런 시스템을 통해 Stripe은 트래픽 급증 시 샤드를 분할하고, 트래픽이 적을 때 수천 개의 데이터베이스를 통합할 수 있습니다.

프록시 서버를 통한 안정성 보장

Stripe은 Go 언어로 개발한 자체 데이터베이스 프록시 서버를 통해 안정성, 확장성, 접근 제어를 관리합니다. 이는 MongoDB 자체의 기능에 추가로 엔터프라이즈급 요구사항을 만족시키는 방법이에요.

MongoDB의 장점들

성능 우수성

MongoDB는 특정 사용 사례에서 뛰어난 성능을 보여줍니다. Cars24의 경우 MongoDB Atlas를 사용해서 3억 명의 사용자를 위한 검색 서비스를 개선했고, 비용을 절반으로 줄였습니다.

MongoDB Atlas Search를 통해 데이터베이스에서 직접 검색 쿼리를 실행할 수 있어, 별도의 검색 엔진과 데이터 동기화가 필요 없어졌어요. 이는 실시간 검색 결과를 제공하면서도 아키텍처를 단순화시켰습니다.

고가용성

MongoDB의 복제 세트는 자동 장애 조치를 제공합니다. 주 노드에 문제가 발생하면 약 1초 내에 보조 노드가 주 노드 역할을 맡아서 서비스 중단을 최소화해요. 이는 Raft 알고리즘을 기반으로 하는 검증된 방식입니다.

사용 편의성

MongoDB Query Language(MQL)은 JavaScript 기반으로, 웹 개발자들에게 친숙합니다. JSON과 유사한 문법을 사용해서 학습 곡선이 완만해요.

// 사용자 검색 예시
db.users.find({
  $and: [
    { "age": { $gte: 18 } },
    { "skills": { $in: ["JavaScript", "React"] } },
    { "location.city": "서울" }
  ]
}).sort({ "createdAt": -1 }).limit(10)

통합된 개발 경험

Cars24의 사례에서 볼 수 있듯이, MongoDB Atlas는 데이터 저장과 검색 기능을 하나의 플랫폼에서 제공합니다. 개발자들은 별도의 도구나 동기화 없이 단일 API로 모든 작업을 처리할 수 있어요.

이는 개발자들이 인덱스 관리나 데이터 동기화보다는 애플리케이션 개발과 제품 구축에 집중할 수 있게 해줍니다.

빠른 개발자 온보딩

MongoDB에 익숙한 개발자들을 빠르게 팀에 합류시킬 수 있습니다. 이는 특히 스타트업이나 빠르게 성장하는 조직에서 중요한 장점이에요.

실제 사용 시 고려사항

MongoDB를 사용할 때 주의해야 할 점들도 있습니다:

JOIN 대신 데이터 중복

MongoDB는 전통적인 JOIN을 지원하지 않습니다. $lookup 연산자를 사용할 수 있지만, RDBMS의 JOIN 대비 성능이 떨어질 수 있어요. 따라서 필요한 데이터를 미리 중복 저장하는 것이 권장됩니다.

트랜잭션 사용 최소화

트랜잭션을 지원하지만, 대규모 트랜잭션은 성능 저하를 일으킬 수 있습니다. 가능하면 임베디드 문서 구조를 사용해서 트랜잭션의 필요성을 줄이는 것이 좋아요.

샤드 키 선택의 중요성

잘못된 샤드 키 선택은 성능 저하와 데이터 불균형을 초래합니다. 샤드 키는 쿼리 패턴과 데이터 분산을 고려해서 신중하게 선택해야 해요.

References