Skip to content

Split View: MongoDB Sharding 완벽 가이드: 샤드 키 설계부터 운영 자동화까지

✨ Learn with Quiz
|

MongoDB Sharding 완벽 가이드: 샤드 키 설계부터 운영 자동화까지

들어가며

단일 MongoDB 인스턴스가 감당할 수 없는 데이터량이나 처리량에 도달하면 Sharding이 필요합니다. Sharding은 데이터를 여러 서버(shard)에 수평 분산하여 읽기/쓰기 성능과 저장 용량을 확장하는 기술입니다.

이 글에서는 MongoDB 7.0+ 기준으로 Sharded Cluster를 구축하고 운영하는 과정을 다룹니다.

Sharded Cluster 아키텍처

MongoDB Sharded Cluster는 세 가지 컴포넌트로 구성됩니다:

  • Shard: 실제 데이터를 저장하는 Replica Set
  • Config Server: 메타데이터와 라우팅 정보를 저장하는 Replica Set
  • mongos: 클라이언트 요청을 적절한 Shard로 라우팅하는 라우터

Docker Compose로 Sharded Cluster 구축

# docker-compose.yml
services:
  # Config Server Replica Set
  config-svr-1:
    image: mongo:7.0
    command: mongod --configsvr --replSet configRS --port 27019
    volumes:
      - config1-data:/data/db

  config-svr-2:
    image: mongo:7.0
    command: mongod --configsvr --replSet configRS --port 27019
    volumes:
      - config2-data:/data/db

  config-svr-3:
    image: mongo:7.0
    command: mongod --configsvr --replSet configRS --port 27019
    volumes:
      - config3-data:/data/db

  # Shard 1 Replica Set
  shard1-1:
    image: mongo:7.0
    command: mongod --shardsvr --replSet shard1RS --port 27018
    volumes:
      - shard1-1-data:/data/db

  shard1-2:
    image: mongo:7.0
    command: mongod --shardsvr --replSet shard1RS --port 27018
    volumes:
      - shard1-2-data:/data/db

  # Shard 2 Replica Set
  shard2-1:
    image: mongo:7.0
    command: mongod --shardsvr --replSet shard2RS --port 27018
    volumes:
      - shard2-1-data:/data/db

  shard2-2:
    image: mongo:7.0
    command: mongod --shardsvr --replSet shard2RS --port 27018
    volumes:
      - shard2-2-data:/data/db

  # Mongos Router
  mongos:
    image: mongo:7.0
    command: mongos --configdb configRS/config-svr-1:27019,config-svr-2:27019,config-svr-3:27019 --port 27017
    ports:
      - '27017:27017'
    depends_on:
      - config-svr-1
      - config-svr-2
      - config-svr-3

volumes:
  config1-data:
  config2-data:
  config3-data:
  shard1-1-data:
  shard1-2-data:
  shard2-1-data:
  shard2-2-data:

초기화 스크립트

#!/bin/bash
# init-sharding.sh

# 1. Config Server Replica Set 초기화
docker exec -it config-svr-1 mongosh --port 27019 --eval '
rs.initiate({
  _id: "configRS",
  configsvr: true,
  members: [
    { _id: 0, host: "config-svr-1:27019" },
    { _id: 1, host: "config-svr-2:27019" },
    { _id: 2, host: "config-svr-3:27019" }
  ]
})'

# 2. Shard 1 Replica Set 초기화
docker exec -it shard1-1 mongosh --port 27018 --eval '
rs.initiate({
  _id: "shard1RS",
  members: [
    { _id: 0, host: "shard1-1:27018" },
    { _id: 1, host: "shard1-2:27018" }
  ]
})'

# 3. Shard 2 Replica Set 초기화
docker exec -it shard2-1 mongosh --port 27018 --eval '
rs.initiate({
  _id: "shard2RS",
  members: [
    { _id: 0, host: "shard2-1:27018" },
    { _id: 1, host: "shard2-2:27018" }
  ]
})'

sleep 10

# 4. Shard를 클러스터에 추가
docker exec -it mongos mongosh --eval '
sh.addShard("shard1RS/shard1-1:27018,shard1-2:27018");
sh.addShard("shard2RS/shard2-1:27018,shard2-2:27018");
'

샤드 키 전략

샤드 키 선택은 Sharding 성능의 80%를 결정합니다.

1. Range Sharding

// 범위 기반 샤딩 - 연속 데이터 조회에 유리
use mydb;
sh.enableSharding("mydb");

// created_at을 샤드 키로 사용
db.orders.createIndex({ created_at: 1 });
sh.shardCollection("mydb.orders", { created_at: 1 });

// 장점: 날짜 범위 쿼리가 단일 샤드에서 처리
db.orders.find({
  created_at: {
    $gte: ISODate("2026-03-01"),
    $lt: ISODate("2026-04-01")
  }
});

// 단점: 최신 데이터가 하나의 샤드에 집중 (핫스팟)

2. Hashed Sharding

// 해시 기반 샤딩 - 균등 분산에 유리
db.users.createIndex({ user_id: 'hashed' })
sh.shardCollection('mydb.users', { user_id: 'hashed' })

// 장점: 쓰기가 모든 샤드에 균등 분산
// 단점: 범위 쿼리 시 모든 샤드를 스캔 (scatter-gather)

// 사전 청크 분할로 초기 불균형 방지
sh.shardCollection('mydb.events', { event_id: 'hashed' }, false, {
  numInitialChunks: 64,
})

3. Compound Shard Key

// 복합 샤드 키 - 가장 권장되는 패턴
db.orders.createIndex({ customer_id: 1, order_date: 1 })
sh.shardCollection('mydb.orders', { customer_id: 1, order_date: 1 })

// customer_id로 카디널리티 확보
// order_date로 범위 쿼리 최적화

// 이 쿼리는 targeted (단일 샤드)
db.orders.find({
  customer_id: 'C12345',
  order_date: { $gte: ISODate('2026-01-01') },
})

4. Zone Sharding (지역 기반)

// Zone Sharding - 데이터 지역성 보장
sh.addShardToZone('shard1RS', 'APAC')
sh.addShardToZone('shard2RS', 'EU')

// Zone 범위 설정
sh.updateZoneKeyRange(
  'mydb.users',
  { region: 'KR' },
  { region: 'KS' }, // KR의 다음 문자열
  'APAC'
)

sh.updateZoneKeyRange('mydb.users', { region: 'DE' }, { region: 'DF' }, 'EU')

// 한국 사용자 데이터는 APAC 샤드에만 저장
// 독일 사용자 데이터는 EU 샤드에만 저장

샤드 키 선택 가이드

기준좋은 샤드 키나쁜 샤드 키
카디널리티높음 (user_id)낮음 (status: active/inactive)
분산도균등 분산편향 (특정 값에 집중)
쿼리 패턴자주 조건에 포함거의 사용 안 함
단조 증가피하거나 해시created_at (핫스팟)
변경 가능MongoDB 5.0+ 가능이전 버전은 변경 불가

샤드 키 변경 (MongoDB 5.0+)

// resharding - 샤드 키 변경
db.adminCommand({
  reshardCollection: 'mydb.orders',
  key: { customer_id: 1, order_date: 1 },
})

// 진행 상황 확인
db.getSiblingDB('admin').aggregate([
  { $currentOp: { allUsers: true, localOps: false } },
  { $match: { type: 'op', 'originatingCommand.reshardCollection': { $exists: true } } },
])

청크 관리

청크 분할과 마이그레이션

// 청크 상태 확인
use config;
db.chunks.find({ ns: "mydb.orders" }).sort({ min: 1 });

// 청크 수 확인
db.chunks.countDocuments({ ns: "mydb.orders" });

// 샤드별 청크 분포
db.chunks.aggregate([
  { $match: { ns: "mydb.orders" } },
  { $group: { _id: "$shard", count: { $sum: 1 } } }
]);

// 수동 청크 분할
sh.splitAt("mydb.orders", { customer_id: "C50000", order_date: ISODate("2026-01-01") });

// 수동 청크 이동
sh.moveChunk("mydb.orders",
  { customer_id: "C50000", order_date: ISODate("2026-01-01") },
  "shard2RS"
);

밸런서 관리

// 밸런서 상태 확인
sh.getBalancerState()
sh.isBalancerRunning()

// 밸런서 시간 제한 (업무 시간 외에만 실행)
db.settings.updateOne(
  { _id: 'balancer' },
  {
    $set: {
      activeWindow: { start: '02:00', stop: '06:00' },
    },
  },
  { upsert: true }
)

// 특정 컬렉션의 밸런싱 비활성화 (마이그레이션 중)
sh.disableBalancing('mydb.orders')
// 재활성화
sh.enableBalancing('mydb.orders')

쿼리 라우팅 이해

// Targeted Query - 단일 샤드에서 처리 (빠름)
// 샤드 키가 쿼리 조건에 포함
db.orders.find({ customer_id: 'C12345' }).explain('executionStats')
// "winningPlan": { "stage": "SINGLE_SHARD" }

// Scatter-Gather Query - 모든 샤드에서 처리 (느림)
// 샤드 키가 쿼리 조건에 미포함
db.orders.find({ product: 'iPhone' }).explain('executionStats')
// "winningPlan": { "stage": "SHARD_MERGE" }

// Broadcast Query - 모든 샤드에 전송
db.orders.aggregate([{ $group: { _id: '$status', total: { $sum: '$amount' } } }])

모니터링

// 샤딩 상태 전체 확인
sh.status();
sh.status(true);  // 상세 정보 포함

// 청크 마이그레이션 히스토리
use config;
db.changelog.find({ what: "moveChunk.commit" }).sort({ time: -1 }).limit(10);

// 현재 진행 중인 마이그레이션
db.locks.find({ _id: "balancer" });

// 각 샤드의 데이터 크기
db.adminCommand({ listDatabases: 1, nameOnly: false });

mongosh 유틸리티

// 컬렉션 통계
db.orders.stats()
db.orders.stats().sharded // true면 샤딩됨

// 샤드별 문서 수
db.orders.getShardDistribution()
// Shard shard1RS: data 2.5GB, docs 5,000,000, chunks 32
// Shard shard2RS: data 2.3GB, docs 4,800,000, chunks 30

운영 주의사항

1. 샤드 추가

// 새 샤드 추가 (서비스 중단 없음)
sh.addShard('shard3RS/shard3-1:27018,shard3-2:27018')

// 밸런서가 자동으로 청크를 새 샤드로 이동
// 이동 완료까지 시간이 걸림

2. 샤드 제거

// 샤드 제거 (draining)
db.adminCommand({ removeShard: 'shard2RS' })

// 진행 상황 확인 (반복 실행)
db.adminCommand({ removeShard: 'shard2RS' })
// "state": "ongoing", "remaining": { "chunks": 15, "dbs": 0 }

// 완료될 때까지 반복 확인

3. 백업 전략

# mongodump로 전체 클러스터 백업 (mongos를 통해)
mongodump --host mongos:27017 --out /backup/$(date +%Y%m%d)

# 또는 각 샤드의 Replica Set을 개별 백업
mongodump --host shard1-1:27018 --out /backup/shard1/$(date +%Y%m%d)
mongodump --host shard2-1:27018 --out /backup/shard2/$(date +%Y%m%d)

정리

전략적합한 케이스주의점
Range범위 쿼리 중심핫스팟 발생 가능
Hashed균등 분산 필요범위 쿼리 비효율
Compound다양한 쿼리 패턴키 설계에 신중해야 함
Zone데이터 지역성 필요불균형 분산 가능

샤드 키 선택은 되돌리기 어려운 결정이므로, 실 데이터와 쿼리 패턴을 충분히 분석한 후 결정하세요.


✅ 퀴즈: MongoDB Sharding 이해도 점검 (7문제)

Q1. Sharded Cluster의 세 가지 구성 요소는?

Shard (데이터 저장), Config Server (메타데이터), mongos (라우터)입니다.

Q2. Range Sharding의 핫스팟 문제란?

단조 증가하는 키(created_at 등)를 사용하면 최신 데이터가 항상 마지막 샤드에 집중됩니다.

Q3. Targeted Query와 Scatter-Gather Query의 차이는?

Targeted는 샤드 키가 쿼리 조건에 포함되어 단일 샤드에서 처리되고, Scatter-Gather는 모든 샤드를 스캔합니다.

Q4. numInitialChunks를 설정하는 이유는?

Hashed Sharding에서 초기 청크를 미리 분할하여 데이터 로드 시 불균형을 방지합니다.

Q5. Zone Sharding의 주요 사용 사례는?

데이터 거주 규정(GDPR 등)에 따라 특정 지역의 데이터를 특정 샤드에만 저장해야 할 때 사용합니다.

Q6. 밸런서의 activeWindow 설정은 왜 필요한가요?

청크 마이그레이션은 I/O를 많이 사용하므로, 업무 시간 외에만 실행하여 서비스 영향을 최소화합니다.

Q7. MongoDB 5.0+에서 추가된 resharding 기능의 의미는?

기존에는 변경 불가했던 샤드 키를 온라인 상태에서 변경할 수 있게 되었습니다.

MongoDB Sharding Complete Guide: From Shard Key Design to Operational Automation

Introduction

When a single MongoDB instance can no longer handle the data volume or throughput, Sharding becomes necessary. Sharding is a technique that horizontally distributes data across multiple servers (shards) to scale read/write performance and storage capacity.

This article covers building and operating a Sharded Cluster based on MongoDB 7.0+.

Sharded Cluster Architecture

A MongoDB Sharded Cluster consists of three components:

  • Shard: Replica Set that stores the actual data
  • Config Server: Replica Set that stores metadata and routing information
  • mongos: Router that routes client requests to the appropriate Shard

Building a Sharded Cluster with Docker Compose

# docker-compose.yml
services:
  # Config Server Replica Set
  config-svr-1:
    image: mongo:7.0
    command: mongod --configsvr --replSet configRS --port 27019
    volumes:
      - config1-data:/data/db

  config-svr-2:
    image: mongo:7.0
    command: mongod --configsvr --replSet configRS --port 27019
    volumes:
      - config2-data:/data/db

  config-svr-3:
    image: mongo:7.0
    command: mongod --configsvr --replSet configRS --port 27019
    volumes:
      - config3-data:/data/db

  # Shard 1 Replica Set
  shard1-1:
    image: mongo:7.0
    command: mongod --shardsvr --replSet shard1RS --port 27018
    volumes:
      - shard1-1-data:/data/db

  shard1-2:
    image: mongo:7.0
    command: mongod --shardsvr --replSet shard1RS --port 27018
    volumes:
      - shard1-2-data:/data/db

  # Shard 2 Replica Set
  shard2-1:
    image: mongo:7.0
    command: mongod --shardsvr --replSet shard2RS --port 27018
    volumes:
      - shard2-1-data:/data/db

  shard2-2:
    image: mongo:7.0
    command: mongod --shardsvr --replSet shard2RS --port 27018
    volumes:
      - shard2-2-data:/data/db

  # Mongos Router
  mongos:
    image: mongo:7.0
    command: mongos --configdb configRS/config-svr-1:27019,config-svr-2:27019,config-svr-3:27019 --port 27017
    ports:
      - '27017:27017'
    depends_on:
      - config-svr-1
      - config-svr-2
      - config-svr-3

volumes:
  config1-data:
  config2-data:
  config3-data:
  shard1-1-data:
  shard1-2-data:
  shard2-1-data:
  shard2-2-data:

Initialization Script

#!/bin/bash
# init-sharding.sh

# 1. Initialize Config Server Replica Set
docker exec -it config-svr-1 mongosh --port 27019 --eval '
rs.initiate({
  _id: "configRS",
  configsvr: true,
  members: [
    { _id: 0, host: "config-svr-1:27019" },
    { _id: 1, host: "config-svr-2:27019" },
    { _id: 2, host: "config-svr-3:27019" }
  ]
})'

# 2. Initialize Shard 1 Replica Set
docker exec -it shard1-1 mongosh --port 27018 --eval '
rs.initiate({
  _id: "shard1RS",
  members: [
    { _id: 0, host: "shard1-1:27018" },
    { _id: 1, host: "shard1-2:27018" }
  ]
})'

# 3. Initialize Shard 2 Replica Set
docker exec -it shard2-1 mongosh --port 27018 --eval '
rs.initiate({
  _id: "shard2RS",
  members: [
    { _id: 0, host: "shard2-1:27018" },
    { _id: 1, host: "shard2-2:27018" }
  ]
})'

sleep 10

# 4. Add Shards to the Cluster
docker exec -it mongos mongosh --eval '
sh.addShard("shard1RS/shard1-1:27018,shard1-2:27018");
sh.addShard("shard2RS/shard2-1:27018,shard2-2:27018");
'

Shard Key Strategies

Shard key selection determines 80% of sharding performance.

1. Range Sharding

// Range-based sharding - advantageous for continuous data queries
use mydb;
sh.enableSharding("mydb");

// Using created_at as shard key
db.orders.createIndex({ created_at: 1 });
sh.shardCollection("mydb.orders", { created_at: 1 });

// Advantage: Date range queries are processed on a single shard
db.orders.find({
  created_at: {
    $gte: ISODate("2026-03-01"),
    $lt: ISODate("2026-04-01")
  }
});

// Disadvantage: Latest data concentrates on a single shard (hotspot)

2. Hashed Sharding

// Hash-based sharding - advantageous for even distribution
db.users.createIndex({ user_id: 'hashed' })
sh.shardCollection('mydb.users', { user_id: 'hashed' })

// Advantage: Writes are evenly distributed across all shards
// Disadvantage: Range queries scan all shards (scatter-gather)

// Pre-split chunks to prevent initial imbalance
sh.shardCollection('mydb.events', { event_id: 'hashed' }, false, {
  numInitialChunks: 64,
})

3. Compound Shard Key

// Compound shard key - the most recommended pattern
db.orders.createIndex({ customer_id: 1, order_date: 1 })
sh.shardCollection('mydb.orders', { customer_id: 1, order_date: 1 })

// customer_id ensures cardinality
// order_date optimizes range queries

// This query is targeted (single shard)
db.orders.find({
  customer_id: 'C12345',
  order_date: { $gte: ISODate('2026-01-01') },
})

4. Zone Sharding (Region-Based)

// Zone Sharding - ensures data locality
sh.addShardToZone('shard1RS', 'APAC')
sh.addShardToZone('shard2RS', 'EU')

// Set zone ranges
sh.updateZoneKeyRange(
  'mydb.users',
  { region: 'KR' },
  { region: 'KS' }, // Next string after KR
  'APAC'
)

sh.updateZoneKeyRange('mydb.users', { region: 'DE' }, { region: 'DF' }, 'EU')

// Korean user data is stored only on the APAC shard
// German user data is stored only on the EU shard

Shard Key Selection Guide

CriteriaGood Shard KeyBad Shard Key
CardinalityHigh (user_id)Low (status: active/inactive)
DistributionEven distributionSkewed (concentrated on specific values)
Query PatternFrequently in conditionsRarely used
MonotonicAvoid or use hashcreated_at (hotspot)
ChangeableMongoDB 5.0+ possibleNot changeable in earlier versions

Shard Key Change (MongoDB 5.0+)

// resharding - changing the shard key
db.adminCommand({
  reshardCollection: 'mydb.orders',
  key: { customer_id: 1, order_date: 1 },
})

// Check progress
db.getSiblingDB('admin').aggregate([
  { $currentOp: { allUsers: true, localOps: false } },
  { $match: { type: 'op', 'originatingCommand.reshardCollection': { $exists: true } } },
])

Chunk Management

Chunk Splitting and Migration

// Check chunk status
use config;
db.chunks.find({ ns: "mydb.orders" }).sort({ min: 1 });

// Check chunk count
db.chunks.countDocuments({ ns: "mydb.orders" });

// Chunk distribution per shard
db.chunks.aggregate([
  { $match: { ns: "mydb.orders" } },
  { $group: { _id: "$shard", count: { $sum: 1 } } }
]);

// Manual chunk split
sh.splitAt("mydb.orders", { customer_id: "C50000", order_date: ISODate("2026-01-01") });

// Manual chunk move
sh.moveChunk("mydb.orders",
  { customer_id: "C50000", order_date: ISODate("2026-01-01") },
  "shard2RS"
);

Balancer Management

// Check balancer status
sh.getBalancerState()
sh.isBalancerRunning()

// Limit balancer to run only outside business hours
db.settings.updateOne(
  { _id: 'balancer' },
  {
    $set: {
      activeWindow: { start: '02:00', stop: '06:00' },
    },
  },
  { upsert: true }
)

// Disable balancing for a specific collection (during migration)
sh.disableBalancing('mydb.orders')
// Re-enable
sh.enableBalancing('mydb.orders')

Understanding Query Routing

// Targeted Query - processed on a single shard (fast)
// Shard key is included in query conditions
db.orders.find({ customer_id: 'C12345' }).explain('executionStats')
// "winningPlan": { "stage": "SINGLE_SHARD" }

// Scatter-Gather Query - processed on all shards (slow)
// Shard key is NOT included in query conditions
db.orders.find({ product: 'iPhone' }).explain('executionStats')
// "winningPlan": { "stage": "SHARD_MERGE" }

// Broadcast Query - sent to all shards
db.orders.aggregate([{ $group: { _id: '$status', total: { $sum: '$amount' } } }])

Monitoring

// Full sharding status check
sh.status();
sh.status(true);  // Including detailed information

// Chunk migration history
use config;
db.changelog.find({ what: "moveChunk.commit" }).sort({ time: -1 }).limit(10);

// Currently ongoing migrations
db.locks.find({ _id: "balancer" });

// Data size per shard
db.adminCommand({ listDatabases: 1, nameOnly: false });

mongosh Utilities

// Collection statistics
db.orders.stats()
db.orders.stats().sharded // true means sharded

// Document count per shard
db.orders.getShardDistribution()
// Shard shard1RS: data 2.5GB, docs 5,000,000, chunks 32
// Shard shard2RS: data 2.3GB, docs 4,800,000, chunks 30

Operational Considerations

1. Adding a Shard

// Add a new shard (no service interruption)
sh.addShard('shard3RS/shard3-1:27018,shard3-2:27018')

// The balancer automatically moves chunks to the new shard
// It takes time to complete the migration

2. Removing a Shard

// Remove a shard (draining)
db.adminCommand({ removeShard: 'shard2RS' })

// Check progress (run repeatedly)
db.adminCommand({ removeShard: 'shard2RS' })
// "state": "ongoing", "remaining": { "chunks": 15, "dbs": 0 }

// Check repeatedly until complete

3. Backup Strategy

# Full cluster backup with mongodump (through mongos)
mongodump --host mongos:27017 --out /backup/$(date +%Y%m%d)

# Or backup each shard's Replica Set individually
mongodump --host shard1-1:27018 --out /backup/shard1/$(date +%Y%m%d)
mongodump --host shard2-1:27018 --out /backup/shard2/$(date +%Y%m%d)

Summary

StrategySuitable CasesConsiderations
RangeRange query-centricPossible hotspot occurrence
HashedNeed for even distributionInefficient range queries
CompoundVarious query patternsKey design requires care
ZoneNeed for data localityPossible uneven distribution

Shard key selection is a decision that is difficult to reverse, so make sure to thoroughly analyze your actual data and query patterns before deciding.


Quiz: MongoDB Sharding Comprehension Check (7 Questions)

Q1. What are the three components of a Sharded Cluster?

Shard (data storage), Config Server (metadata), mongos (router).

Q2. What is the hotspot problem in Range Sharding?

When using monotonically increasing keys (like created_at), the latest data always concentrates on the last shard.

Q3. What is the difference between Targeted Query and Scatter-Gather Query?

Targeted queries include the shard key in the query conditions and are processed on a single shard, while Scatter-Gather queries scan all shards.

Q4. Why set numInitialChunks?

In Hashed Sharding, pre-splitting initial chunks prevents imbalance during data loading.

Q5. What is the main use case for Zone Sharding?

Used when data residency regulations (GDPR, etc.) require storing data from specific regions only on specific shards.

Q6. Why is the balancer's activeWindow setting needed?

Chunk migration uses heavy I/O, so limiting it to non-business hours minimizes service impact.

Q7. What is the significance of the resharding feature added in MongoDB 5.0+?

It enables changing shard keys online, which was previously impossible.

Quiz

Q1: What is the main topic covered in "MongoDB Sharding Complete Guide: From Shard Key Design to Operational Automation"?

Hands-on practice with MongoDB Sharding architecture and shard key strategies. Covers Range/Hashed/Zone Sharding, chunk splitting and balancing, and operational considerations through practical exercises.

Q2: Describe the Sharded Cluster Architecture.A MongoDB Sharded Cluster consists of three components: Shard: Replica Set that stores the actual data Config Server: Replica Set that stores metadata and routing information mongos: Router that routes client requests to the appropriate Shard Building a Sharded Cluster with Docke...

Q3: Explain the core concept of Shard Key Strategies. Shard key selection determines 80% of sharding performance. 1. Range Sharding 2. Hashed Sharding 3. Compound Shard Key 4. Zone Sharding (Region-Based)

Q4: What are the key aspects of Shard Key Selection Guide? Shard Key Change (MongoDB 5.0+)

Q5: How does Chunk Management work? Chunk Splitting and Migration Balancer Management