Files
clean-architecture-backend-…/docs/superpowers/specs/2026-08-11-mongodb-document-persistence-platform-design.md

32 KiB

MongoDB 문서 영속성 플랫폼 설계서

  • 문서 상태: 구현 기준 설계
  • 기준일: 2026-08-11
  • 대상 프로젝트: Java 21 / Spring Boot 4.1 기반 Backend Skeleton
  • 모듈 루트: modules/mongodb
  • 루트 패키지: io.backend.skeleton.mongodb
  • 요구사항 원본: MongoDB 문서 영속성 플랫폼 심층 리서치

1. 설계 목적

이 설계의 목적은 Spring Data MongoDB를 다시 감싼 공통 CRUD 라이브러리를 만드는 것이 아니다. 도메인 모듈이 MongoDB의 Document, Repository, Query 의미와 Index 요구를 직접 소유하면서도, 다음 기술 결정은 모든 서비스가 같은 기준으로 재사용하도록 만드는 것이다.

Document Modeling
→ BSON Mapping
→ Atomic Write
→ Consistency Profile
→ Session / Transaction
→ Retry / Ambiguous Outcome
→ Query / Aggregation Guardrail
→ Schema / Index Manifest
→ Pagination / Bulk
→ Change Stream
→ Security / Observability
→ Topology / Release Gate

플랫폼은 MongoDB를 관계형 저장소처럼 평탄화하지 않는다. 반대로 Native Driver와 runCommand()를 일반 애플리케이션에 무제한 노출하지도 않는다. MongoDB의 단일 문서 원자성, BSON 표현, Aggregation, Replica Set, Change Stream, Sharding, Encryption 의미론을 유지하면서 잘못된 사용을 사전에 차단한다.

2. 최상위 설계 결정

번호 결정 구현 결과
D-01 도메인이 @Document, Repository, Query, Index Requirement, Schema Version을 소유한다. 플랫폼에는 범용 CommonMongoRepository<T, ID>를 만들지 않는다.
D-02 Local 기본 토폴로지는 Single-node Replica Set이다. Transaction, Retryable Write, Change Stream을 Local에서 동일하게 검증한다.
D-03 Standalone은 smoke test만 지원한다. 운영 Profile이나 Stable Release Gate로 인정하지 않는다.
D-04 D1/D2 Runtime Client는 Stable API V1과 apiStrict=true를 기본으로 한다. 일반 CRUD·Query·Transaction·Change Stream 경로의 호환성을 제한한다.
D-05 D3 Capability Client와 D4 Admin Client를 분리한다. Stable API 밖 기능과 관리 명령을 일반 Runtime에서 우회하지 못한다.
D-06 UUID·Decimal·시간·type metadata 표현을 Manifest로 고정한다. 배포나 라이브러리 변경으로 BSON 표현이 암묵적으로 바뀌지 않는다.
D-07 부분 변경은 Update Operator를 우선한다. save() 기반 전체 Document 교체로 인한 Lost Update를 줄인다.
D-08 전체 Document 교체에는 optimistic revision을 요구한다. @Version 또는 expected revision predicate를 사용한다.
D-09 Transaction보다 단일 Document 원자 연산을 우선한다. Multi-document invariant에만 Transaction을 사용한다.
D-10 Transaction 본문 Retry와 Commit Retry를 분리한다. TransientTransactionError는 전체 본문, UnknownTransactionCommitResult는 Commit만 재시도한다.
D-11 Query·Aggregation·Index는 등록된 operation/manifest를 요구한다. 자유형 JSON Query와 무제한 Pipeline을 차단한다.
D-12 Change Stream은 at-least-once projector다. physical change event를 업무 Integration Event로 직접 공개하지 않는다.
D-13 TTL은 물리 cleanup이다. 정확한 업무 Scheduler 또는 접근 차단의 유일한 근거로 사용하지 않는다.
D-14 GridFS는 compatibility adapter다. 신규 파일 Source of Truth는 기존 Fileserver/Object Storage를 사용한다.
D-15 Sharding·Time Series·Encryption·Search·Vector·Multi-tenancy는 선택 모듈이다. Stable Starter의 기본 dependency와 권한에 포함하지 않는다.

3. 범위와 비범위

3.1 Stable 범위

Mapping Manifest
Repository / MongoTemplate 통합
Imperative / Reactive 실행 경로
단일 Document 원자 Update
Optimistic Lock
Replica Set Transaction
Consistency Profile
Retry / Error Translation
Query Guardrail
Aggregation Guardrail
Schema / Index Manifest
Keyset Pagination
Bulk Partial Result
Change Stream
TTL Cleanup Contract
GeoJSON / 2dsphere
Security
Observability
Replica Set Testkit

3.2 Advanced 범위

Sharding-aware Query
Time Series
CSFLE
Queryable Encryption Equality / Range
Change Stream → Messaging Bridge
Shared Collection Multi-tenancy

3.3 Experimental 범위

MongoDB Search
Vector Search
Hybrid Search
Database-per-tenant
Collection-per-tenant
Reshard orchestration
Atlas/provider 고유 기능

3.4 명시적 비지원

CommonMongoRepository<T, ID>
Runtime arbitrary runCommand
운영 auto-index creation
Standalone 운영 계약
TTL 기반 정확한 Scheduler
Change Stream 원본의 외부 업무 이벤트 공개
신규 GridFS 파일 플랫폼
Java FQCN을 장수 BSON schema로 강제
무제한 skip pagination
무제한 aggregation / regex / result

4. 지원 기준

구성 Stable 기준 정책
Java 21 프로젝트 Runtime 기준
Spring Boot 4.1.x BOM 개별 Driver 버전 override 금지
Spring Data MongoDB 5.1.x Repository·Template 통합
MongoDB Java Driver Boot BOM 관리 직접 버전 고정 금지
MongoDB Server 8.0 최신 패치 Primary Certification Lane
MongoDB 7.0 최신 7.0 패치 Compatibility Lane
Stable API V1 D1/D2 strict 기본
Local Single-node Replica Set 기본 개발 환경
운영 Stable Gate 3-node Replica Set Failover 검증 필수
Sharding 실제 Sharded Cluster Advanced Gate
Search/Vector Atlas Local + 실제 목표 배포 기능별 Gate
Encryption 실제 KMS·Key Vault 환경 기능별 Gate

MongoDB 8.0/7.0 Stable 계약에서는 validationAction=errorAndLog를 사용하지 않는다. Stable Validation Action은 errorwarn이다.

5. 공개 계층

D1 Standard Document Persistence
├─ Spring Data Repository
├─ Typed Query / Projection
├─ Mapping Manifest
├─ Atomic Update Primitive
└─ Optimistic Revision

D2 Advanced Document Operations
├─ MongoTemplate
├─ Transaction / Session
├─ Bulk
├─ Aggregation
├─ Keyset / Cursor
└─ Change Stream

D3 Explicit Mongo Capability
├─ Native BSON
├─ Time Series
├─ Search / Vector
├─ CSFLE / QE
└─ Sharding-aware Operations

D4 Admin Plane
├─ Collection
├─ Validator
├─ Index
├─ Migration
├─ Shard / Refine / Reshard
└─ Repair / Verification

D3도 raw client escape가 아니다. 모든 D3 호출은 다음 순서를 통과한다.

Capability 등록 확인
→ Database Profile 확인
→ Collection allowlist
→ Operation Name 필수
→ Timeout / maxTimeMS
→ Consistency Profile
→ Result / Batch Limit
→ Trace
→ Log Redaction
→ Command Category 검증
→ D4 Command 차단
→ 실행

6. 모듈 구조

6.1 Stable 모듈

modules/mongodb/
├── mongodb-core-api
├── mongodb-spring-data
├── mongodb-imperative
├── mongodb-reactive
├── mongodb-query
├── mongodb-aggregation
├── mongodb-transaction
├── mongodb-index-schema
├── mongodb-change-stream
├── mongodb-geospatial
├── mongodb-migration-core
├── mongodb-migration-flamingock
├── mongodb-observability
├── mongodb-security
├── mongodb-spring-boot-starter
├── mongodb-testkit-core
├── mongodb-testkit-replicaset
├── mongodb-testkit-failover
└── mongodb-testkit-migration

6.2 Advanced·Experimental 모듈

modules/mongodb-advanced/
├── mongodb-sharding
├── mongodb-timeseries
├── mongodb-csfle
├── mongodb-queryable-encryption
├── mongodb-search
├── mongodb-vector-search
├── mongodb-tenancy-shared
├── mongodb-tenancy-database
├── mongodb-change-stream-messaging-bridge
├── mongodb-gridfs-compat
├── mongodb-testkit-sharded
└── mongodb-testkit-atlas

6.3 Dependency 규칙

mongodb-core-api
  → Java 표준 라이브러리만

mongodb-spring-data
  → core-api

mongodb-imperative / mongodb-reactive
  → core-api
  → spring-data

mongodb-query
  → core-api
  → spring-data

mongodb-aggregation
  → core-api
  → query

mongodb-transaction
  → core-api
  → spring-data

mongodb-index-schema
  → core-api
  → spring-data

mongodb-change-stream
  → core-api
  → reactive

mongodb-geospatial
  → core-api
  → spring-data

mongodb-migration-flamingock
  → migration-core
  → index-schema

mongodb-spring-boot-starter
  → Stable 모듈만

Advanced 모듈
  → Starter에 자동 포함하지 않음

7. 핵심 타입

7.1 Operation·Profile

public record MongoOperationName(String value) {
    public MongoOperationName {
        if (value == null || !value.matches("[a-z][a-z0-9.-]{2,95}")) {
            throw new IllegalArgumentException("invalid MongoDB operation name");
        }
    }
}

public record DatabaseProfileName(String value) {}
public record CollectionProfileName(String value) {}

public record MongoOperationContext(
        MongoOperationName operationName,
        DatabaseProfileName databaseProfile,
        CollectionProfileName collectionProfile,
        MongoConsistencyProfile consistency,
        Duration timeout) {
}

Operation name은 metric·trace·policy key로 사용하므로 사용자 ID나 동적 값이 들어갈 수 없다.

7.2 Consistency Profile

public enum MongoConsistencyProfile {
    PRIMARY_LOCAL,
    PRIMARY_MAJORITY,
    CAUSAL_MAJORITY,
    STALE_READ_ALLOWED,
    SNAPSHOT_TRANSACTION,
    MONGO_SHORT_WRITE
}
Profile Read Preference Read Concern Write Concern 용도
PRIMARY_LOCAL primary local acknowledged 일반 저지연 작업
PRIMARY_MAJORITY primary majority majority rollback 저항·내구성
CAUSAL_MAJORITY primary 기본 majority majority read-your-writes
STALE_READ_ALLOWED secondaryPreferred local/majority 없음 명시적 stale read
SNAPSHOT_TRANSACTION primary snapshot majority multi-document snapshot
MONGO_SHORT_WRITE primary profile 값 profile 값 짧은 write transaction

STALE_READ_ALLOWED는 이름으로 위험을 드러낸다. readOnly=true를 자동으로 secondary routing 조건으로 사용하지 않는다.

7.3 실행 결과

public enum MongoExecutionOutcome {
    NOT_SENT,
    NO_WRITE_PERFORMED,
    WRITE_CONFIRMED,
    PARTIAL_BULK_WRITE,
    WRITE_RESULT_UNKNOWN,
    TRANSACTION_COMMIT_UNKNOWN
}

WRITE_RESULT_UNKNOWNTRANSACTION_COMMIT_UNKNOWN은 명백한 실패가 아니다. 동일 업무 본문을 무조건 재실행하지 않고 version, unique key, idempotency record, transaction record를 조회해 복구한다.

7.4 Capability

public enum MongoSupportLevel {
    STABLE,
    ADVANCED,
    EXPERIMENTAL,
    UNSUPPORTED
}

public record MongoCapabilitySupport(
        String capability,
        MongoSupportLevel level,
        Map<String, String> constraints) {
}

Capability는 boolean만 반환하지 않는다. Time Series, Sharding, Encryption, Search처럼 제약이 큰 기능은 토폴로지·버전·권한·비지원 조합을 함께 반환한다.

8. Client와 권한 경계

Runtime Strict Client
├─ Stable API V1
├─ apiStrict=true
├─ App read/write credential
└─ D1/D2

Capability Client
├─ capability allowlist
├─ Stable API strict 여부 기능별 결정
├─ capability credential
└─ D3

Admin Client
├─ Runtime Starter에서 기본 미등록
├─ migration/deployment job 전용
├─ admin credential
└─ D4

일반 Runtime에서 MongoClient, MongoDatabase, MongoCollection<Document> Bean을 이름 없이 전역 공개하지 않는다. Spring Data가 내부적으로 사용하는 Bean은 존재하지만 애플리케이션이 직접 주입하지 않도록 ArchUnit·Bean visibility·문서 규칙을 적용한다.

9. Document 모델링 계약

9.1 Embed와 Reference

같이 읽음
AND 같이 변경함
AND 크기가 bounded
→ Embed

독립 lifecycle
OR unbounded growth
OR 여러 Aggregate에서 공유
OR 독립 sharding 필요
→ Manual Reference
특성 Embed Manual Reference
항상 함께 조회 권장 가능
같은 명령에서 변경 권장 신중
bounded 필수 불필요
무한 배열 금지 권장
공유 데이터 신중 권장
독립 보안·보존 신중 권장
hot write 신중 권장

9.2 Document Modeling Manifest

도메인별로 다음 Manifest를 제공한다.

collections:
  orders:
    document-type: order
    schema-version: 3
    max-estimated-document-bytes: 2097152
    embedded-collections:
      lineItems:
        max-elements: 200
      stateHistory:
        max-elements: 100
    references:
      customerId:
        target-collection: customers
        required: true

플랫폼은 16 MiB 한계에 가까운 설정을 허용하지 않고 안전 여유가 포함된 프로젝트 상한을 요구한다. 실제 serialized BSON 크기를 contract test로 측정한다.

9.3 GridFS 경계

신규 파일 저장
→ Fileserver Application
→ Filesystem / Object Storage Adapter

MongoDB Document
→ FileId / ContentKey Reference

GridFS
→ Legacy read / migration compatibility only

10. BSON 표현 Manifest

mongodb:
  mapping:
    uuid-representation: STANDARD
    big-decimal-representation: DECIMAL128
    big-integer-representation: STRING
    instant-representation: BSON_DATE
    local-date-time: REJECT_UNLESS_CONVERTER_REGISTERED
    enum-representation: STRING
    type-metadata: ALIAS_FOR_LONG_LIVED_COLLECTIONS
Java/Domain 타입 BSON 정책
ObjectId ObjectId Mongo 전용 내부 ID에 허용
UUID/UUIDv7 Binary UUID STANDARD 고정
String Domain ID String ObjectId 자동 변환 차단
BigDecimal Decimal128 정밀도·범위 검사
BigInteger 명시적 컬렉션별 고정
Instant BSON Date Stable
LocalDateTime 암묵 저장 금지 명시 Converter 요구
Enum String rename은 migration
Money Document amount/currency 고정
Encrypted field BinData Encryption 모듈 소유

다음 차이는 모두 schema 차이다.

absent != null
[] != absent
"1" != 1
String decimal != Decimal128
String object id != ObjectId

10.1 Golden BSON Gate

모든 지원 타입은 다음 흐름을 통과한다.

Java object
→ MappingMongoConverter
→ BSON snapshot
→ 실제 Replica Set 저장
→ raw BSON read-back
→ Java object round-trip

11. Type Metadata

Collection 정책
내부 단기 기본 _class 허용 가능
장수·다중 버전 @TypeAlias 필수
외부 공유 명시적 documentType
package refactoring 가능 FQCN 금지

_class 제거는 모든 다형성 Mapping에 동일하게 적용하지 않는다. Collection별 TypeMetadataPolicy를 사용한다.

12. Schema Validation·Versioning·Migration

12.1 Validation 계층

Bean Validation
→ 입력·Java 객체 조기 실패

MongoDB JSON Schema
→ 저장 BSON type/required/range 최종 방어

Domain Invariant
→ 업무 규칙
단계 validationLevel validationAction
신규 Collection strict error
Legacy 정비 시작 moderate warn
Backfill migration profile warn 또는 error
정비 완료 strict error

12.2 Schema Version

public record DocumentSchemaVersion(int value) {
    public DocumentSchemaVersion {
        if (value < 0) throw new IllegalArgumentException("negative schema version");
    }
}
schemaVersion 없음
→ Legacy V0

신규 Write
→ Current Version만

지원 범위 밖 Version
→ MongoDataSchemaUnsupportedException

12.3 변경 절차

Dual Reader
→ New Writer
→ Rate-limited Backfill
→ Version 잔존량 검증
→ Legacy Index 제거
→ Legacy Reader 제거

12.4 Migration SPI

public interface MongoMigration {
    MigrationId id();
    MigrationChecksum checksum();
    MigrationPrecondition precondition();
    MigrationResult execute(MigrationContext context);
    MigrationPostcondition postcondition();
}

필수 기능:

Ledger
Distributed Lock
Dry Run
Batch
Checkpoint
Resume
Rate Limit
maxTimeMS
Precondition
Postcondition
Forward Fix
Operator Metadata

신규 기본 Adapter는 mongodb-migration-flamingock으로 두되, 플랫폼 공개 계약은 Flamingock 타입에 의존하지 않는다. Mongock 신규 채택은 금지한다. Liquibase MongoDB는 후속 D4 Adapter로 추가할 수 있다.

13. 쓰기 모델

상황 기본 연산
신규 Document insert
전체 재계산 versioned save/replace
일부 필드 updateOne + operator
Counter $inc
상태 전이 expected state + $set
bounded Set $addToSet
배열 원소 positional / arrayFilters
변경 결과 반환 findAndModify
경쟁 생성 unique index + upsert
독립 다건 bulk
하나의 multi-document invariant transaction

13.1 Atomic Update API

public interface MongoAtomicOperations {
    <T> AtomicUpdateResult<T> updateOne(
            MongoOperationContext context,
            Class<T> documentType,
            AtomicFilter filter,
            AtomicUpdate update,
            ReturnDocumentMode returnMode);
}

자유형 BSON filter/update를 받지 않고 등록된 field descriptor와 operator allowlist를 사용한다.

13.2 Optimistic Revision

전체 Document 교체와 custom update는 다음 predicate를 사용한다.

filter:
  _id = id
  version = expected

update:
  business fields
  version = version + 1

Conflict Retry는 stale object 재저장이 아니다.

최신 Document 재조회
→ 전체 Use Case 재계산
→ 외부 side effect 부재 확인
→ 제한 재시도

14. Session·Transaction

14.1 선택 기준

단일 Document invariant
→ atomic update

여러 Document invariant
→ transaction

MongoDB + HTTP
→ transaction 밖

MongoDB + Object Storage
→ saga/state machine

MongoDB + Messaging
→ outbox 또는 change-stream bridge

14.2 Transaction API

public interface MongoTransactionExecutor {
    <T> T execute(MongoTransactionProfile profile, Supplier<T> work);
}

public interface ReactiveMongoTransactionExecutor {
    <T> Publisher<T> execute(
            MongoTransactionProfile profile,
            Supplier<? extends Publisher<T>> work);
}

14.3 Retry 분리

TransientTransactionError
→ 새 Session
→ Transaction 본문 전체 재실행

UnknownTransactionCommitResult
→ 본문 재실행 금지
→ Commit만 재시도
→ 최종 불명 시 reconciliation

모든 Retry는 max attempts, max elapsed time, jitter, deadline을 가진다.

15. 오류 모델

MongoPersistenceException
├─ MongoDuplicateKeyException
├─ MongoSchemaValidationException
├─ MongoOptimisticConflictException
├─ MongoWriteConflictException
├─ MongoTransactionTransientException
├─ MongoTransactionCommitUnknownException
├─ MongoWriteConcernException
├─ MongoReadConcernException
├─ MongoServerSelectionException
├─ MongoConnectionException
├─ MongoTimeoutException
├─ MongoCursorException
├─ MongoDocumentTooLargeException
├─ MongoBulkPartialFailureException
├─ MongoShardRoutingException
├─ MongoResumeException
├─ MongoEncryptionException
└─ MongoOperationRejectedException

오류에는 다음만 보존한다.

operationName
databaseProfile
collectionProfile
operationType
consistencyProfile
retryable
ambiguous
errorLabels
serverCode
attempt
elapsed
traceId

Document, Query parameter, credential, plaintext encrypted field, resume token, shard key 실제 값은 저장하지 않는다.

16. Query Guardrail

16.1 Query 등급

등급 API 사용 위치
Q1 Derived Query, Projection 일반 Domain
Q2 Criteria, Custom Repository, Querydsl 동적 Query
Q3 Aggregation, Search/Vector, 제한 Native BSON Advanced
Q4 Collection/Index/Admin command D4

16.2 정책

Sort field allowlist
Projection field allowlist
Field path allowlist
Operator allowlist
Collation profile
Hint allowlist
maxTimeMS
Result limit
Regex 길이·문자 클래스 제한
Dynamic collection 차단

다음 API는 제공하지 않는다.

Document executeUserBson(String json);
Document runCommand(Map<String, Object> input);

17. Aggregation Guardrail

등급 Stage 정책
A1 match/project/set/unset/bounded limit Stable
A2 sort/group/unwind/lookup/bucket Resource Budget 필수
A3 facet/graphLookup/large window/union Advanced Review
A4 out/merge/admin write stage D4

기본 설정:

strictMapping=true
maxTimeMS=profile-defined
resultLimit=bounded
allowDiskUse=explicit resource profile
writeStage=false
lookupCollection=allowlist
operationName=required

18. Schema·Index Manifest

collections:
  orders:
    owner: order-domain
    validator: classpath:/mongodb/orders-schema-v3.json
    validation-level: strict
    validation-action: error
    indexes:
      - name: uq_order_number
        keys:
          orderNumber: 1
        unique: true
        expected-usage: order.find-by-number
      - name: ix_customer_created_id
        keys:
          customerId: 1
          createdAt: -1
          _id: -1
        expected-usage: order.find-recent

Index Manifest 필드:

name
key order
unique
partialFilter
sparse
collation
expireAfterSeconds
hidden
wildcardProjection
geo options
shardKeySupport
expectedUsage
owner
metadataOwnership

metadataOwnership 값:

APPLICATION
MONGODB_MANAGED
ENCRYPTION_MANAGED
SEARCH_MANAGED

운영에서는 자동 Index 생성이 아니라 diff·approval·D4 apply를 사용한다.

Local/Test: apply 허용
Dev: apply + diff
Staging: diff + 승인 apply
Prod: D4만 생성·삭제·collMod

Index 삭제:

deprecated 표시
→ usage 확인
→ hidden
→ 관측
→ explain regression
→ 승인 drop

19. Pagination·Cursor·Bulk

19.1 Pagination

작은 Admin 목록 → Page
일반 목록 → Slice
대규모 목록 → Keyset
Batch 처리 → Cursor + batchSize
무한 변경 구독 → Change Stream

Keyset은 항상 유일한 tie-breaker를 포함한다.

sort: createdAt DESC, _id DESC
cursor: createdAt + _id + sortVersion

19.2 Bulk

public record MongoBulkResult(
        int requested,
        int inserted,
        int modified,
        int deleted,
        int upserted,
        List<MongoBulkItemFailure> failures,
        boolean partial) {
}

Ordered·Unordered Bulk 모두 부분 성공을 보존한다. 성공 항목을 다시 실행하지 않는다.

20. Change Stream

20.1 상태

STARTING
RUNNING
RESUMING
HISTORY_LOST
FAILED
STOPPED

20.2 Checkpoint 계약

Event 처리
→ idempotent projector 완료
→ checkpoint 저장

이 순서는 duplicate 가능성을 허용하지만 event loss를 방지한다. Projector는 stable event identity와 idempotency key를 사용한다.

20.3 Resume

resumeAfter
→ 일반 resume token

startAfter
→ invalidate 이후 재개

oplog history 부족
→ HISTORY_LOST
→ 자동으로 최신부터 시작하지 않음
→ 운영 복구 정책 필요

20.4 Messaging 경계

MongoDB Physical Change
→ Internal Projector
→ Stable Integration Event
→ Messaging Platform

DB 변경과 Event가 반드시 같은 commit에 있어야 하면 Outbox를 사용한다.

21. TTL·Geo·특수 Collection 경계

21.1 TTL

Query 접근 조건: expiresAt > applicationNow
TTL Index: physical cleanup

TTL 삭제 지연을 정상으로 취급한다. 정확한 업무 상태 전이는 별도 Scheduler가 담당한다.

21.2 Geospatial

Stable 기본:

GeoJSON
2dsphere
longitude, latitude 순서
거리 단위 명시
bounded near/within query

21.3 Time Series

Time Series는 일반 Collection 계약을 상속하지 않는다.

기능 일반 Time Series
Validator O X
Change Stream O X
CSFLE O X
Transaction Write O X
Search 조건부 X
TTL O O
Document limit 16 MiB 별도 제한

22. Sharding 경계

Application Plane:

ShardKeyDescriptor
ShardAwareQueryValidator
CollectionRoutingProfile
Targeted/Scatter Classification
Telemetry

Admin Plane:

shardCollection
analyzeShardKey
refineCollectionShardKey
reshardCollection
zone
balancer
shard add/remove

모든 shard-aware write는 shard key 또는 routing evidence를 요구한다. @Sharded 하나로 충분하다고 간주하지 않는다.

23. Encryption 경계

mongodb-csfle
mongodb-queryable-encryption
요구 Capability
Query 불필요 PII randomized 또는 unindexed
equality deterministic 또는 QE equality
range QE range
prefix/suffix/substring MongoDB 8.0 Stable 비지원
tenant key explicit resolver
collection setup D4
rotation D4 + runbook

CSFLE와 QE를 같은 Collection에 동시에 적용하지 않는다. QE 내부 metadata collection과 __safeContent__는 ENCRYPTION_MANAGED ownership으로 보호한다.

24. Search·Vector 경계

GeoJSON / 2dsphere → Stable
Legacy $text → Compatibility only
MongoDB Search → Advanced
Vector Search → Advanced
Hybrid Search → Advanced
Search Index Admin → D4

Index 생성 완료와 READY 상태를 구분한다. Atlas Local은 빠른 CI, 실제 목표 배포는 Release Gate다.

25. Multi-tenancy 경계

모델 등급
Single DB Stable
Shared Collection + tenantId Advanced
Database per Tenant Experimental
Collection per Tenant 제한 Experimental
Cluster per Tenant Infra Profile

Shared Collection은 모든 find/update/delete, aggregation, change stream에 tenant predicate를 적용하고 unique index·shard key에 tenant 의미를 검증한다. raw tenant ID는 log·metric에 남기지 않는다.

26. Security

Principal 분리:

mongo-app-read
mongo-app-write
mongo-change-stream
mongo-migration
mongo-search-admin
mongo-shard-admin
mongo-encryption-admin
mongo-dba

Production 기본 금지:

auth disabled
TLS disabled
admin credential 공유
connection string credential source 저장
raw user BSON 실행
arbitrary runCommand
Document 전체 logging
plaintext encrypted field logging

Query 입력은 allowlist로 변환하고 Regex는 길이·패턴·timeout을 제한한다.

27. Observability

Driver native ObservabilitySettings를 기준으로 한다.

영역 Signal
Pool size, checked-out, wait, failure
SDAM topology, primary, heartbeat
Operation count, latency, result, timeout
Write inserted, modified, deleted, upsert, concern failure
Retry driver/app retry, labels
Transaction duration, abort, body retry, commit retry, unknown
Aggregation duration, disk use, result count
Query Efficiency examined/returned, index, spill
Sharding targeted/scatter
Change Stream lag, resume, history lost
TTL cleanup lag
Migration progress, checkpoint
Search index readiness

허용 Tag:

mongoProfile
databaseProfile
collectionProfile
operationName
operationType
result
failureCategory
consistencyProfile

금지 Tag:

documentId
rawTenantId
dynamicCollectionName
queryParameter
fullBson
resumeToken
shardKeyValue
plaintextPII
credential

28. Spring Boot 설정

backend:
  mongodb:
    profiles:
      default:
        uri-secret: secret://mongodb/default-uri
        topology: REPLICA_SET
        stable-api:
          version: V1
          strict: true
          deprecation-errors: true
        consistency-default: PRIMARY_MAJORITY
        timeout:
          server-selection: 3s
          connect: 2s
          socket-read: 5s
          operation: 3s
        pool:
          min-size: 2
          max-size: 40
          max-wait-time: 500ms
        mapping:
          uuid-representation: STANDARD
          big-decimal-representation: DECIMAL128
        index:
          runtime-auto-create: false
        security:
          tls-required: true
          authentication-required: true

Startup 실패 조건:

Production에서 Standalone
Production에서 auth/TLS 비활성
Runtime auto-index 활성
UUID/Decimal 표현 미설정
Stable D1/D2에서 apiStrict 미설정
Required Replica Set인데 topology 불일치
Transaction 활성인데 Replica Set 아님
Change Stream 활성인데 watch capability 없음
Admin Client가 일반 Runtime credential과 동일
Unsupported schema version
Dynamic collection profile

29. 테스트 아키텍처

Unit
→ Manifest / Policy / Classifier

Repository Slice
→ Converter / Repository / Query

Single-node Replica Set
→ Mapping / Atomic / Transaction / Change Stream

3-node Replica Set
→ Failover / Retry / Commit Unknown / Resume

Sharded Cluster
→ Routing / Chunk Migration / Cross-shard / Reshard

Atlas Local
→ Search / Vector quick CI

Actual Target Deployment
→ Search / Vector / Encryption Release Gate

필수 장애 테스트:

Primary kill
Network partition
Server selection timeout
Write response loss
TransientTransactionError
UnknownTransactionCommitResult
Bulk partial failure
Change Stream process kill
Resume token loss
Oplog history loss
Index drift
Schema validation mismatch
Credential rotation

30. Release Gate

Stable 릴리스 조건:

Java 21 / Boot 4.1 BOM 확인
MongoDB 7.0 compatibility
MongoDB 8.0 primary certification
Single-node RS contract
3-node RS failover
Golden BSON snapshot
Atomic update race
Optimistic conflict
Transaction body/commit retry 분리
Index/Schema manifest drift
Keyset pagination
Bulk partial result
Change Stream resume/history loss
TLS/RBAC/redaction
Driver native observability

Advanced 기능은 해당 모듈과 실제 환경 Gate를 통과하기 전 Starter에 포함하지 않는다.

31. 구현 단계

단계 범위 완료 조건
1 Foundation BOM, modules, profiles, topology, stable API Context startup·topology gate
2 Document Core BSON manifest, converter, type metadata, modeling Golden BSON·size guard
3 Write·Consistency atomic update, revision, profile, transaction, retry race·failover·commit ambiguity
4 Schema·Query validator, migration, query, aggregation, index strictMapping·diff·explain
5 Scale·Stream keyset, cursor, bulk, TTL, change stream partial result·resume·kill
6 Operations security, observability, starter, runbook least privilege·redaction
7 Advanced sharding, time series, encryption, search/vector, tenancy capability-specific gate

32. 완료 정의

다음 질문에 모두 구현과 테스트로 답할 수 있어야 한다.

Document가 bounded라는 증거가 있는가?
BSON 타입 표현이 배포 간 고정되는가?
부분 Update가 전체 Document를 덮지 않는가?
Read/Write Concern의 실제 보장을 호출자가 아는가?
Transaction body retry와 commit retry가 분리되는가?
Bulk 일부 성공이 보존되는가?
Query와 Index가 Release 전에 연결되는가?
Change Stream checkpoint 경계가 명확한가?
TTL을 Scheduler로 오해하지 않는가?
Shard Key 없는 Query를 감지하는가?
암호화 metadata를 drift cleanup이 삭제하지 않는가?
실제 Replica Set·Sharded·Atlas 환경에서 검증되는가?

33. 요구사항 추적표

리서치 영역 설계 절 구현 계획 영역
기준선·Topology 4, 8, 28 Task 15, 4548
D1~D4 경계 5, 6 Task 1, 38, 39
Document Modeling 9 Task 10
BSON 표현 10, 11 Task 6~9
Schema·Migration 12 Task 11, 18~22, 46
Atomic Write·Optimistic 13 Task 13~14
Consistency·Transaction 14 Task 23~28
오류·Retry 15 Task 45, 2728
Query·Aggregation 16~17 Task 15~17
Index 18 Task 18~20
Pagination·Bulk 19 Task 29~31
Change Stream 20 Task 33~35
TTL·Geo 21 Task 32, 36
Security·Observability 26~27 Task 37~40, 47
Starter·Gate 28~30 Task 41~50
Advanced 22~25 별도 Advanced 계획