왜 'majority'가 MongoDB에서 기본 read concern가 아닌가?

발행: (2025년 12월 31일 오후 05:58 GMT+9)
15 min read
원문: Dev.to

Source: Dev.to

위 링크에 있는 전체 글을 번역하려면, 해당 글의 텍스트를 제공해 주시겠어요?
코드 블록, URL 및 마크다운 형식은 그대로 유지하고, 본문만 한국어로 번역해 드리겠습니다.

TL;DR

전통적인 SQL 데이터베이스와 동기 요청‑응답 흐름에 익숙하고—같은 트랜잭션이나 세션에서 쓰기를 바로 읽는 경우—MongoDB에서는 majority read concern를 사용하세요. 이는 데이터베이스에서 기대할 수 있는 가장 높은 격리 수준과 내구성을 제공합니다.

  • 기본값은 아니지만, 연결에 대해 변경해도 안전합니다.
  • 기본값은 비동기 통신을 사용하는 이벤트‑드리븐, 마이크로‑서비스 아키텍처에 최적화되어 있으며, 때때로 나중에 롤백될 수 있는 상태를 읽더라도 낮은 지연 시간을 선호합니다.

MongoDB가 기본적으로 가장 강력한 일관성을 활성화하지 않는 이유

PostgreSQL 사용자는 일반적으로 쓰기가 인정된 후에만 다른 세션에 보이기를 기대합니다. 이는 자동‑커밋 DML이든 명시적인 COMMIT이든 관계없이.

MongoDB에서는 유사한 ACID 보장을 얻기 위해 majority 읽기 컨선활성화해야 하며, 이는 기본값이 아닙니다.

MongoDB가 분산 데이터베이스에서 전체 ACID 의미론이라는 가장 강력한 일관성 옵션을 제공하면서도, 성능에 큰 영향을 주지 않는 것처럼 보여도 기본적으로 이를 활성화하지 않는다는 점은 놀라울 수 있습니다.

이러한 불일치는 설계 선택의 배경에 대한 더 깊은 검토를 촉발했습니다.

역사적 배경: SQL vs. NoSQL

  • SQL 표준: 격리 수준은 먼저 이상 현상(동시 세션이 동일한 데이터를 읽고 쓸 때 발생할 수 있는 현상)으로 정의되었습니다.

    • 이러한 정의는 추상 모델보다 잠금 기반 구현에 묶여 있었으며, 읽기와 쓰기가 잠금을 사용하고 활성 트랜잭션이 단일 현재 데이터베이스 상태를 공유한다는 전제를 두었습니다.
  • 현대 데이터베이스는 확장성을 위해 종종 다른 설계를 선택합니다:

설계예시주요 특징
MVCC를 이용한 논블로킹 읽기PostgreSQL, MongoDB읽기는 스냅샷을 보며, write skew와 같은 이상 현상이 나타날 수 있음; Snapshot Isolation(SI) 등 격리 수준을 지원합니다. PostgreSQL은 SI 수준을 Repeatable Read라 부르며 SQL 표준에 맞춥니다.
논블로킹 쓰기(낙관적 동시성)MongoDB쓰기 충돌이 즉시 감지되어 예외가 발생하고, 잠금을 기다리는 대신 재시도 가능한 예외를 발생시킵니다.

MongoDB에서 격리와 내구성

MongoDB에서 격리와 내구성을 이해하려면 읽기쓰기 우선순위를 별도로 고려해야 합니다—특히 읽기와 쓰기가 서로 다른 서버에 도달할 수 있는 복제·분산 환경에서는 더욱 그렇습니다. 그런 다음 쓰기 후 읽기를 할 때 이들이 어떻게 상호 작용하는지 살펴볼 수 있습니다.

격리 vs. 내구성 (ACID의 ID)

개념보장 내용
격리서로 다른 세션의 읽기와 쓰기가 서로 어떻게 보이는지를 정의합니다. 트랜잭션이 완료될 때까지 커밋되지 않은 쓰기의 중간 상태를 숨겨야 하며, 이전에 커밋된 쓰기를 놓치는 오래된 읽기를 방지해야 합니다.
내구성데이터가 한 번 기록되면 영구적으로 유지되며 장애가 발생해도 손실되지 않아야 합니다. 이미 읽힌 데이터도 영구적으로 보존된다는 것이 보장되어야 합니다.

원래 이 정의들은 단일 노드 데이터베이스를 전제로 했습니다. 현대 시스템에서는 내구성이 네트워크 및 데이터 센터 장애까지 처리해야 하므로, 데이터가 로컬 디스크가 아니라 여러 노드에 걸쳐 지속됩니다.

일반적인 커밋 흐름 (SQL 스타일)

  1. 커밋이 시작됩니다.
  2. WAL이 로컬 디스크에 플러시됩니다로컬 내구성.
  3. WAL이 원격 디스크에 플러시됩니다전역 내구성.
  4. 변경 사항이 다른 세션에 보이게 됩니다 (격리 종료).
  5. 클라이언트 세션에 커밋이 확인됩니다.

위 순서는 다음과 일치합니다:

  • synchronous_commit = on인 PostgreSQL, 또는
  • w:majority와 읽기 세션에서 majority 읽기 우선순위를 사용하는 MongoDB.

다른 구성에서는 이 단계들의 순서를 바꿀 수 있습니다:

시스템 / 설정순서 차이
Oracle (기본값)redo 로그가 플러시되기 에 변경 사항을 보이게 합니다 (paranoid_concurrency_mode가 설정되지 않은 경우).
PostgreSQL synchronous_commit = local 또는 MongoDB w:1확인이 전역 내구성 에 발생합니다.
MongoDB local 읽기 우선순위데이터가 내구성이 확보되기 에 보이게 됩니다.

“Missing” 기본값: 왜 가장 강력한 시퀀스를 사용하지 않을까?

가장 강력한 격리‑및‑내구성 시퀀스(위 단계 1‑5)는 MongoDB에서 기본값이 아니다. 그 이유 중 하나는 단일 데이터베이스 상태에 대한 읽기와 쓰기 잠금이 상호 배타적이라고 가정하기 때문에 SQL 표준에서는 전혀 설명되지 않은 추가적인 이상 현상이 존재한다는 점이다.

MVCC가 도입하는 두 개의 논리적 시간

  1. 읽기 시간 – 트랜잭션 시작 시점(또는 Read Committed에서 문장 시작 시점). 모든 읽기는 이 시점의 스냅샷을 사용한다.
  2. 쓰기 시간 – 트랜잭션 종료 시점; 모든 쓰기는 커밋 시 원자적으로 나타난다.

읽기 시간 때문에 …

핵심 요점: MVCC 시스템에서는 응용 프로그램이 쓰기 확인 응답이 도착하기 전에 다른 서비스에 알리는 경우가 많다. 이는 쓰기가 이미 완료되었다고 가정하기 때문이다. 이러한 기대는 읽기 컨선이(write concern) 쓰기가 내구성 있게 보이고(visible) 동시에 지속 가능함을 보장할 때만 안전하다.

Summary

  • majority read concern in MongoDB provides the strongest isolation and durability, comparable to the default behavior of many SQL databases. → MongoDB의 majority 읽기 우선순위는 가장 강력한 격리와 내구성을 제공하며, 많은 SQL 데이터베이스의 기본 동작과 비교할 수 있습니다.
  • It isn’t the default because MongoDB targets event‑driven, low‑latency micro‑service architectures, where the trade‑off of occasional stale reads is acceptable. → 이것이 기본값이 아닌 이유는 MongoDB가 이벤트‑드리븐, 저지연 마이크로서비스 아키텍처를 목표로 하기 때문이며, 여기서는 가끔 발생하는 오래된 읽기에 대한 트레이드오프가 허용됩니다.
  • The causality anomaly introduced by MVCC (read‑time …) → MVCC가 도입한 인과 관계 이상(읽기 시점 …)

Tip: When using w:1, select the local read concern to avoid this anomaly. w:1 is not the default; it is chosen only when lower latency is preferred over guaranteed durability. → Tip: w:1을 사용할 때는 이 이상을 피하기 위해 local read concern을 선택하세요. w:1기본값이 아니며, 보장된 내구성보다 낮은 지연 시간이 우선될 때만 선택됩니다.

지연 시간 vs. 내구성 트레이드‑오프

  • Local acknowledgment (w:1 / synchronous_commit = local)

    • Pros: 낮은 지연 시간; 쓰기가 빠르게 완료됩니다.
    • Cons: 장애 발생 시 이벤트 손실 위험이 높아집니다(쓰기가 롤백될 수 있음).
  • Majority acknowledgment (w:majority / synchronous_commit = on)

    • Pros: 더 강력한 내구성; 노드 또는 데이터센터 장애가 발생해도 쓰기가 유지됩니다.
    • Cons: 원격 확인을 기다리기 때문에 추가 네트워크 지연이 발생합니다.

다수 확인을 사용하더라도, 마이크로서비스 B가 다수가 쓰기를 커밋하기 전에 읽으면 read‑after‑write 이상 현상이 발생할 수 있습니다. MongoDB의 local read concern을 사용하면 이 이상 현상을 없앨 수 있지만, 이후 롤백될 수 있는 데이터를 노출할 위험이 있습니다.

기본 읽기 우선순위 및 그 근거

  • 기본 읽기 우선순위(MongoDB에서는 흔히 “majority”)는 초기 NoSQL 시스템의 주요 사용 사례였던 이벤트‑드리븐 아키텍처와 잘 맞습니다.
  • 개발자는 일반적으로 읽기가 최신 변경 사항을 반환하기를 기대하며, 해당 변경 사항이 원본 스레드에서 완전히 확인되지 않았더라도 마찬가지입니다.

전통적인 아키텍처

MongoDB를 보다 전통적이고 내구성에 중점을 둔 환경에서 사용할 때:

  • “majority” 읽기 우선순위가 선호됩니다.
  • 쓰기 확인을 기다리는 동안 이미 쓰기 지연 시간이 소요되었으므로 추가적인 성능 페널티가 발생하지 않습니다.

“majority” 작동 방식:

  • 읽기 타임스탬프를 마지막 커밋 시점으로 설정하면서 읽기는 로컬에서 수행됩니다.
  • 드물게 (예: 인스턴스 시작, 롤백, 사용 불가능하거나 지연된 세컨더리) 일시적으로 블록될 수 있습니다.
  • 일반적으로 눈에 띄는 성능 영향은 없습니다.

MongoDB의 구성 가능한 일관성 모델

많은 SQL 데이터베이스가 모든 DML 작업에 대해 일관성 보장을 일괄적으로 적용하는 것과 달리, MongoDB는 개발자가 적절한 일관성 및 성능 설정을 선택하도록 더 많은 책임을 부여합니다.

주요 구성 옵션

  1. Write Concern – 내구성을 결정

    • 예시: w:majority는 네트워크 또는 데이터 센터 장애에 대한 복원력을 제공합니다.
  2. Read Concern – 읽기의 가시성 보장을 결정

    • 예시:
      • majority – 가장 최근에 다수에 의해 커밋된 데이터를 읽습니다.
      • snapshot – 다중 샤드 트랜잭션에 대해 더 강력한 일관성을 제공합니다.
  3. Read Preference – 읽기가 라우팅되는 위치를 결정

    • 복제본을 통해 읽기를 확장하고, 허용 가능한 경우 약간의 오래된 데이터를 허용할 수 있습니다.

이 세 가지 설정을 조정함으로써 MongoDB는 다양한 일관성 및 성능 요구 사항에 맞게 조정될 수 있습니다.

Back to Blog

관련 글

더 보기 »

분산 시스템에서의 이중 쓰기 문제

개요 dual‑write problem은 단일 논리적 작업이 두 개 이상의 독립적인 시스템을 업데이트해야 할 때 발생합니다—예를 들어, 데이터베이스에 데이터를 영구 저장하고 …

Handshake: 현대 API의 보이지 않는 비용

무슨 일이 일어나고 있나요? 로컬에서 API가 20 ms에 응답하고, 로그에 병목 현상이 없으며, 데이터베이스는 이미 최적화되었고 코드는 깔끔합니다. 프로…