MongoDB 일관성 이해하기: 개발자를 위한 BASE 모델 설명
이 심층 가이드를 통해 MongoDB의 일관성 모델을 이해하세요. 전통적인 ACID 데이터베이스와 대비하여 BASE 모델이 어떻게 MongoDB의 확장성을 이끄는지 배웁니다. 결과적 일관성을 명확히 하고, MongoDB의 유연한 읽기 및 쓰기 고려 사항을 탐구하며, 최적의 성능과 데이터 무결성을 위해 데이터베이스를 조정하는 실용적인 예제를 제공합니다. 분산 NoSQL 플랫폼에서 탄력적이고 고성능 애플리케이션을 구축하는 데 이러한 선택이 왜 중요한지 이해하세요.
MongoDB 일관성 이해하기: 개발자를 위한 BASE 모델 설명
MongoDB 일관성은 사람들이 "MongoDB는 결과적으로 일관성이 있다"는 한 문장으로 축약하기 때문에 혼란스럽습니다. 이는 너무 단순해서 유용하지 않습니다. MongoDB 복제 세트는 쓰기 고려 사항, 읽기 고려 사항, 읽기 선호도 및 장애 조치 발생 여부에 따라 일부 작업에는 강한 동작을 제공하고 다른 작업에는 오래된 읽기를 제공할 수 있습니다.
PostgreSQL 또는 MySQL에서 오는 경우 가장 큰 변화는 일관성이 전체 애플리케이션에 대해 하나의 고정된 설정이 아니라는 점입니다. 각 경로에 필요한 보장을 선택합니다. 체크아웃 흐름, 알림 피드 및 분석 대시보드는 모두 동일한 최신성이나 내구성이 필요하지 않습니다.
ACID 대 BASE: 일관성에 대한 두 가지 접근 방식
MongoDB의 모델을 살펴보기 전에 데이터베이스 일관성에 대한 두 가지 주요 패러다임인 ACID와 BASE를 이해하는 것이 도움이 됩니다.
ACID 속성 (전통적인 RDBMS)
PostgreSQL 또는 MySQL과 같은 전통적인 관계형 데이터베이스 관리 시스템(RDBMS)은 일반적으로 ACID 속성을 준수하여 트랜잭션 워크로드에서 특히 데이터 안정성을 보장합니다. ACID는 다음을 의미합니다:
- 원자성(Atomicity): 각 트랜잭션은 단일하고 분할할 수 없는 단위로 처리됩니다. 완전히 완료(커밋)되거나 전혀 발생하지 않습니다(롤백). 부분 트랜잭션은 없습니다.
- 일관성(Consistency): 트랜잭션은 데이터베이스를 하나의 유효한 상태에서 다른 상태로 전환합니다. 데이터베이스에 기록된 데이터가 정의된 모든 규칙과 제약 조건에 따라 유효해야 함을 보장합니다.
- 격리성(Isolation): 동시 트랜잭션은 격리되어 실행되며, 순차적으로 실행되는 것처럼 보입니다. 동시 트랜잭션의 결과는 하나씩 실행된 것과 동일합니다.
- 지속성(Durability): 트랜잭션이 커밋되면 정전, 충돌 또는 기타 시스템 오류가 발생하더라도 커밋된 상태로 유지됩니다. 변경 사항은 영구적으로 저장됩니다.
ACID는 강력한 일관성을 보장하므로 금융 거래와 같이 엄격한 데이터 무결성이 필요한 애플리케이션에 이상적입니다.
BASE 속성 (MongoDB와 같은 NoSQL 데이터베이스)
대조적으로, MongoDB를 포함한 많은 NoSQL 데이터베이스는 즉각적인 일관성보다 가용성과 파티션 허용 오차를 우선시하며, 종종 BASE 모델에 부합합니다. BASE는 다음을 의미합니다:
- 기본적으로 가용(Basically Available): 시스템은 가용성을 보장합니다. 즉, 데이터의 가장 최신 버전을 보장할 수 없더라도 모든 요청에 응답합니다.
- 소프트 상태(Soft State): 시스템의 상태는 입력 없이도 시간이 지남에 따라 변경될 수 있습니다. 이는 데이터가 비동기적으로 시스템을 통해 전파되는 결과적 일관성 모델 때문입니다.
- 결과적 일관성(Eventual Consistency): 주어진 데이터 항목에 대해 더 이상 업데이트가 없으면, 결국 해당 항목에 대한 모든 접근이 마지막 업데이트 값을 반환합니다. 분산 시스템의 모든 노드에서 변경 사항이 표시되기까지 지연이 있습니다.
BASE를 준수하는 시스템은 분산 환경에서 높은 가용성과 확장성을 위해 설계되어 데이터 전파에 약간의 지연을 허용할 수 있는 애플리케이션에 적합합니다.
MongoDB의 결과적 일관성 이해하기
MongoDB는 읽기가 보조 노드에서 제공되거나 쓰기가 아직 모든 곳에 복제되지 않은 경우 결과적 일관성 동작을 보일 수 있습니다. 즉, MongoDB 복제 세트에 데이터를 쓸 때 기본 노드는 쓰기를 승인한 다음 해당 쓰기를 보조 노드에 비동기적으로 복제합니다. 기본 노드는 쓰기가 지속되도록 보장하지만, 클라이언트에 성공을 알리기 전에 모든 보조 노드가 따라잡을 때까지 기다리지 않습니다. 결과적으로 보조 노드에서 후속 읽기가 최신 쓰기를 즉시 반영하지 않을 수 있지만, 결국에는 일관성이 유지됩니다.
이 설계 선택은 MongoDB가 수평적으로 확장되고 높은 가용성을 유지하는 데 기본이 됩니다. 모든 작업에 대해 모든 노드가 완벽하게 동기화될 것을 요구하지 않음으로써 MongoDB는 일부 노드가 일시적으로 사용 불가능하거나 지연되더라도 읽기 및 쓰기를 계속 제공할 수 있습니다.
결과적 일관성의 장단점
- 장점: 더 높은 가용성, 더 나은 성능(쓰기 지연 시간 감소), 분산 시스템에 대한 더 큰 확장성.
- 단점: 애플리케이션은 오래된 데이터를 읽을 가능성을 처리하도록 설계되어야 합니다. 이는 모든 복제본에서 즉각적인 일관성이 중요한 작업에서 특히 관련이 있습니다.
MongoDB의 읽기 및 쓰기 고려 사항: 일관성 조정
MongoDB는 기본적으로 결과적 일관성을 사용하지만, 개발자가 작업별로 일관성 수준을 조정할 수 있는 강력한 메커니즘인 읽기 고려 사항과 쓰기 고려 사항을 제공합니다. 이를 통해 애플리케이션의 필요에 따라 일관성, 가용성 및 성능의 균형을 맞출 수 있습니다.
쓰기 고려 사항
쓰기 고려 사항은 쓰기 작업에 대해 MongoDB에서 요청된 승인 수준을 설명합니다. 작업이 성공을 반환하기 전에 복제 세트 구성원 중 몇 명이 쓰기를 확인해야 하는지를 결정합니다.
주요 쓰기 고려 사항 옵션:
w: 쓰기를 승인해야 하는mongod인스턴스 수를 지정합니다.w: 0: 승인 없음. 클라이언트는 데이터베이스로부터 응답을 기다리지 않습니다. 이는 가장 높은 처리량을 제공하지만 쓰기 직후 기본 노드가 충돌하면 데이터 손실 위험이 있습니다.w: 1(기본값): 기본 노드만 승인. 기본 노드가 쓰기를 수신하고 처리했음을 확인합니다. 빠르지만 쓰기가 보조 노드에 복제되었음을 보장하지 않습니다.w: "majority": 복제 세트 구성원의 과반수(기본 노드 포함)로부터 승인. 이는 더 강력한 내구성 보장을 제공하며, 쓰기가 대부분의 노드에 커밋됩니다. 기본 노드가 실패하면 데이터가 다른 노드의 과반수에 존재함을 보장합니다.
j:mongod인스턴스가 쓰기를 승인하기 전에 디스크 저널에 써야 하는지 여부를 지정합니다. 저널링을 활성화하면(j: true)mongod프로세스가 충돌하더라도 내구성을 제공합니다.wtimeout: 쓰기 고려 사항이 충족되어야 하는 시간 제한. 이 시간 내에 쓰기 고려 사항이 충족되지 않으면 쓰기 작업이 오류를 반환합니다.
쓰기 고려 사항 예시 (w: "majority" 및 저널링 사용):
db.products.insertOne(
{ item: "laptop", qty: 50 },
{ writeConcern: { w: "majority", j: true, wtimeout: 5000 } }
);
팁: 내구성과 고가용성이 필요한 중요한 데이터의 경우
w: "majority"와j: true를 권장합니다. 덜 중요한 데이터나 높은 처리량의 로깅의 경우w: 1또는w: 0도 허용될 수 있습니다.
읽기 고려 사항
읽기 고려 사항을 사용하면 읽기 작업에 대한 일관성 및 격리 수준을 지정할 수 있습니다. 특히 복제 환경에서 MongoDB가 쿼리에 반환하는 데이터를 결정합니다.
주요 읽기 고려 사항 옵션:
local: 클라이언트가 연결된 인스턴스(기본 또는 보조)에서 데이터를 반환합니다. 이는 독립 실행형 인스턴스 및 보조 노드의 기본값입니다. 복제 세트의 경우 가장 낮은 지연 시간을 제공하지만 오래된 데이터를 반환할 수 있습니다.available: 데이터가 복제 세트의 과반수에 기록되었음을 보장하지 않고 인스턴스에서 데이터를 반환합니다.local과 유사하게 가용성과 낮은 지연 시간을 우선시합니다.majority: 복제 세트 구성원의 과반수에 의해 승인된 데이터를 반환합니다. 이는 데이터가 내구성이 있고 롤백되지 않음을 보장합니다.local또는available보다 강력한 일관성을 제공하지만 잠재적으로 더 높은 지연 시간이 발생할 수 있습니다.linearizable: 반환된 데이터가 전역적으로 가장 최근에 승인된 쓰기를 반영함을 보장합니다. 이는 가장 강력한 읽기 고려 사항으로, 읽기가majority쓰기 고려 사항에 의해 승인된 모든 쓰기를 볼 수 있도록 합니다. 상당한 성능 오버헤드가 발생할 수 있으며 기본 노드에서만 읽기에 사용할 수 있습니다.snapshot(다중 문서 트랜잭션용): 쿼리가 특정 시점의 데이터를 반환하여 트랜잭션 내에서 여러 문서에 걸쳐 읽기가 일관되도록 보장합니다.
읽기 고려 사항 예시 (majority 사용):
db.products.find(
{ item: "laptop" },
{ readConcern: { level: "majority" } }
);
경고:
linearizable는 강력한 일관성을 제공하지만 성능에 영향을 미칩니다. 엄격한 순서와 쓰기의 전역적 가시성이 중요한 시나리오에만 신중하게 사용하십시오.
BASE와 결과적 일관성이 확장에 중요한 이유
BASE 모델과 결과적 일관성은 MongoDB의 확장성과 고가용성을 위한 핵심 요소입니다:
- 수평 확장(샤딩): 즉각적인 일관성을 완화함으로써 MongoDB는 여러 샤드(복제 세트 클러스터)에 데이터를 분산할 수 있습니다. 각 샤드는 상대적으로 독립적으로 작동하므로 데이터베이스가 수평으로 확장되어 대규모 데이터 세트와 높은 처리량을 처리할 수 있으며, 전체 분산 시스템의 모든 노드가 항상 완벽하게 동기화될 필요는 없습니다.
- 고가용성 및 내결함성: 복제 세트에서 기본 노드를 사용할 수 없게 되면 보조 노드에서 새 기본 노드를 선출할 수 있습니다. 결과적 일관성은 장애 조치 중에도 보조 노드가 계속 읽기를 제공할 수 있고(읽기 고려 사항에 따라 다름) 시스템이 계속 사용 가능함을 의미합니다. 기본 노드가 모든 쓰기에 대해 모든 보조 노드를 기다려야 한다면 단일 지연 보조 노드가 전체 시스템의 병목 현상을 일으킬 수 있습니다.
- 성능: 덜 엄격한 일관성 요구 사항은 쓰기 작업의 지연 시간을 낮추고 전체 처리량을 높이는 것을 의미합니다. 시스템이 진행하기 전에 모든 노드의 승인을 기다리기 위해 차단할 필요가 없기 때문입니다.
읽기 및 쓰기 고려 사항을 통해 조정 가능한 일관성을 제공함으로써 MongoDB는 개발자가 정보에 입각한 결정을 내릴 수 있도록 지원합니다. 높은 가용성과 처리량을 우선시하는 애플리케이션(예: IoT 데이터 수집, 실시간 분석)은 약한 일관성을 선택할 수 있습니다. 반대로 강력한 데이터 무결성이 필요한 애플리케이션(예: 금융 거래, 재고 업데이트)은 관련 성능 절충을 수용하면서 더 강력한 일관성 수준을 선택할 수 있습니다.
실용적인 고려 사항 및 모범 사례
- 중요 데이터 식별: 강력한 일관성이 절대적으로 필요한 데이터(예: 계좌 잔액)와 결과적 일관성을 허용할 수 있는 데이터(예: 사용자 프로필 업데이트, 세션 데이터)를 결정합니다.
- 멱등성 설계: 약한 쓰기 고려 사항을 사용할 때 쓰기가 기본 노드에서는 성공하지만 보조 노드로 복제되기 전에 실패하여 후속 롤백이 발생하고 클라이언트가 쓰기가 실패했다고 믿을 수 있습니다. 클라이언트가 작업을 재시도하면 중복이 발생할 수 있습니다. 가능한 경우 작업을 멱등성 있게 설계하십시오.
- 클라이언트 측 자신의 쓰기 읽기: 사용자가 쓰기를 수행한 후 즉시 읽기를 시도하면 약한 읽기 고려 사항으로 보조 노드에서 읽을 때 오래된 데이터를 볼 수 있습니다. 사용자가 항상 자신의 최근 쓰기를 읽도록 하려면 해당 읽기를 기본 노드로 보내거나
majority읽기 고려 사항을 사용하고 특정 작업에 대해majority쓰기 고려 사항을 함께 사용하는 것을 고려하십시오. - 모니터링:
rs.printReplicationInfo()또는 MongoDB Atlas 메트릭을 사용하여 복제 세트 지연을 주시하십시오. 높은 복제 지연은 결과적 일관성 문제를 악화시킬 수 있습니다.
MongoDB 일관성에 대해 더 유용한 사고 방식
MongoDB는 모든 상황에서 단순히 "결과적으로 일관성이 있는" 것은 아니며, 그렇게 취급하면 조잡한 설계로 이어집니다. 승인된 쓰기 후 기본 노드에서 읽는 것은 몇 초 뒤처진 보조 노드로 라우팅된 읽기와 매우 다르게 동작할 수 있습니다. w: 1로 승인된 쓰기는 w: "majority"로 승인된 쓰기와 다른 위험 프로필을 가집니다. 일관성 스토리는 읽기 선호도, 읽기 고려 사항, 쓰기 고려 사항, 토폴로지 및 잘못된 시기에 장애 조치가 발생하는지 여부에 따라 달라집니다.
일반 제품 페이지의 경우 결과적 일관성이 괜찮을 수 있습니다. 관리자가 제품 설명을 변경하고 고객이 보조 노드에서 잠시 동안 이전 설명을 보더라도 비즈니스 영향은 일반적으로 작습니다. 주문 확인 페이지의 경우 허용 오차가 다릅니다. 고객이 주문을 제출하고 다음 화면에서 주문을 찾을 수 없으면(잠시라도) 시스템이 고장난 것처럼 느껴집니다. 여기서는 원시 처리량보다 자신의 쓰기 읽기 동작이 더 중요합니다.
실용적인 패턴은 사용자 대면 확인 경로에는 더 강력한 설정을 사용하고 백그라운드 또는 분석 경로에는 더 느슨한 설정을 사용하는 것입니다. 예를 들어, 주문 쓰기는 w: "majority"를 사용하고 즉시 확인 읽기는 기본 노드로 갈 수 있습니다. 어제의 활동을 집계하는 대시보드는 약간의 지연이 일반적으로 허용되므로 보조 노드에서 읽을 수 있습니다. 로그 수집 파이프라인은 청구 원장보다 약한 승인을 허용할 수 있지만 충돌 또는 장애 조치 중에 손실될 수 있는 것에 대해 정직해야 합니다.
"사용 가능"이라는 단어에도 주의하십시오. 분산 데이터베이스는 장애 중에도 일부 요청을 계속 제공할 수 있지만 모든 요청이 동일한 보장으로 성공할 수 있다는 의미는 아닙니다. 기본 노드 선거는 짧은 기간 동안 쓰기를 일시 중지합니다. 보조 노드는 읽기 선호도가 허용하는 경우에만 읽기를 제공할 수 있습니다. 네트워크 파티션은 MongoDB가 더 이상 과반수에 속하지 않는 노드에서 쓰기를 수락하는 것보다 안전을 선택하도록 강제할 수 있습니다. 이는 결함이 아닙니다. 복제된 데이터가 두 개의 충돌하는 기록으로 분할되는 것을 방지하는 절충입니다.
다음은 애플리케이션 설계 노트에 작성할 결정입니다:
중요한 계정, 주문 및 재고 변경:
- writeConcern: majority
- 사용자 자신의 작업을 확인할 때 기본 노드에서 다시 읽기
- 드라이버가 지원하는 경우 재시도 가능 쓰기 사용
- 요청 ID 또는 고유 키로 쓰기 작업을 멱등성 있게 만들기
검색 페이지, 피드 페이지, 분석 및 중요하지 않은 프로필 표시:
- 보조 노드 읽기가 허용될 수 있음
- UI에서 오래된 결과 허용
- 최신성이 중요할 때 타임스탬프 표시
이런 종류의 노트는 "MongoDB는 BASE다"라고 말하고 넘어가는 것보다 더 유용합니다. 미래의 엔지니어에게 오래된 읽기가 허용되는 위치와 허용되지 않는 위치를 알려줍니다.