SAABlog
데이터베이스고급

DynamoDB 파티션 키 설계: 핫 파티션 방지와 성능 최적화

DynamoDB 파티션 키를 올바르게 설계하여 핫 파티션을 방지하고 최대 성능을 이끌어내는 방법을 알아봅니다.

PHILOLAMB-
DynamoDB파티션 키NoSQL성능 최적화데이터 모델링

관련 시험 도메인

  • Domain 3: Design High-Performing Architectures

핵심 요약 (BLUF)

파티션 키는 카디널리티가 높고 접근 패턴이 균등한 속성을 선택하세요. 핫 파티션이 발생하면 프로비저닝된 용량을 낭비하고 쓰로틀링이 발생합니다. 샤딩 기법으로 부하를 분산시킬 수 있습니다.

시험 팁

시험 핵심: "핫 파티션 → 쓰로틀링 → 해결책: 높은 카디널리티 키 또는 쓰기 샤딩"

파티션 키가 왜 중요한가?

DynamoDB는 파티션 키의 해시값을 기반으로 데이터를 물리적 파티션에 분산합니다.

                    ┌─────────────────────────────────────────┐
                    │           DynamoDB 테이블               │
                    └─────────────────────────────────────────┘
                                      │
                    ┌─────────────────┼─────────────────┐
                    │                 │                 │
                    ▼                 ▼                 ▼
            ┌──────────────┐  ┌──────────────┐  ┌──────────────┐
            │  파티션 A    │  │  파티션 B    │  │  파티션 C    │
            │  (Hash 0-33) │  │  (Hash 34-66)│  │  (Hash 67-99)│
            │              │  │              │  │              │
            │  user_001    │  │  user_002    │  │  user_003    │
            │  user_004    │  │  user_005    │  │  user_006    │
            └──────────────┘  └──────────────┘  └──────────────┘

파티션별 처리 한도

항목한도
읽기 용량3,000 RCU/초
쓰기 용량1,000 WCU/초
저장 용량10GB

시험 팁

암기: 파티션당 3,000 RCU, 1,000 WCU, 10GB

핫 파티션(Hot Partition)이란?

특정 파티션에 요청이 집중되어 해당 파티션의 처리 한도를 초과하는 현상입니다.

핫 파티션 발생 예시

잘못된 설계: 파티션 키 = "date" (YYYY-MM-DD)

┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│ 2026-01-24   │  │ 2026-01-25   │  │ 2026-01-26   │
│              │  │              │  │ 🔥 HOT!     │
│  접근: 1%    │  │  접근: 5%    │  │  접근: 94%   │
│              │  │              │  │              │
│  한도 여유   │  │  한도 여유   │  │  쓰로틀링!   │
└──────────────┘  └──────────────┘  └──────────────┘

결과: 오늘 날짜 파티션에 모든 요청이 집중되어 쓰로틀링 발생

핫 파티션의 영향

  1. 쓰로틀링: ProvisionedThroughputExceededException 발생
  2. 비용 낭비: 다른 파티션의 용량은 사용되지 않음
  3. 성능 저하: 요청 지연 또는 실패

좋은 파티션 키의 조건

1. 높은 카디널리티 (Cardinality)

파티션 키의 고유값 개수가 많을수록 좋습니다.

파티션 키카디널리티평가
user_id수백만✅ 매우 좋음
order_id수백만✅ 매우 좋음
genre10-20❌ 낮음
status3-5❌ 매우 낮음
date365⚠️ 낮음 (접근 패턴 문제)

2. 균등한 접근 패턴

키 값들에 대한 요청이 고르게 분산되어야 합니다.

좋은 예: user_id
- user_001: 100 요청/초
- user_002: 95 요청/초
- user_003: 105 요청/초
→ 균등 분산 ✅

나쁜 예: celebrity_id
- celebrity_001 (인기 연예인): 10,000 요청/초 🔥
- celebrity_002: 10 요청/초
- celebrity_003: 5 요청/초
→ 집중 현상 ❌

3. 복합 키 활용

파티션 키 + 정렬 키로 더 세밀한 설계가 가능합니다.

설계 패턴파티션 키정렬 키용도
사용자별 주문user_idorder_timestamp사용자의 주문 이력 조회
게시판board_idpost_timestamp게시판의 글 목록
IoT 센서device_idtimestamp센서 데이터 시계열

핫 파티션 해결 전략

전략 1: 쓰기 샤딩 (Write Sharding)

파티션 키에 무작위 접미사를 추가하여 부하를 분산합니다.

원본 키: "popular_item_001"
    ↓
샤딩된 키: "popular_item_001#shard_0"
          "popular_item_001#shard_1"
          "popular_item_001#shard_2"
          ...
          "popular_item_001#shard_9"

구현 예시:

import random

def get_sharded_key(item_id, shard_count=10):
    shard = random.randint(0, shard_count - 1)
    return f"{item_id}#shard_{shard}"

# 쓰기
dynamodb.put_item(
    TableName='Products',
    Item={
        'pk': {'S': get_sharded_key('popular_item_001')},
        'view_count': {'N': '1'}
    }
)

# 읽기 (모든 샤드 집계)
for i in range(10):
    response = dynamodb.query(
        TableName='Products',
        KeyConditionExpression='pk = :pk',
        ExpressionAttributeValues={
            ':pk': {'S': f'popular_item_001#shard_{i}'}
        }
    )

시험 팁

쓰기 샤딩 단점: 읽기 시 모든 샤드를 조회해야 하므로 읽기 복잡도가 증가합니다. 쓰기 집중 워크로드에 적합합니다.

전략 2: 시간 기반 파티셔닝

날짜 대신 더 세분화된 시간 단위를 사용합니다.

나쁜 예: pk = "2026-01-26" (하루에 하나의 핫 파티션)

좋은 예: pk = "2026-01-26#hour_14" (시간별 분산)
더 좋은 예: pk = "2026-01-26#14:30" (30분 단위 분산)

전략 3: 복합 속성 결합

여러 속성을 결합하여 카디널리티를 높입니다.

나쁜 예: pk = "status" (PENDING, COMPLETED, FAILED)
    → 3개 파티션만 사용

좋은 예: pk = "status#customer_id"
    → PENDING#cust_001, COMPLETED#cust_002, ...
    → 수천 개 파티션으로 분산

Adaptive Capacity

DynamoDB는 핫 파티션 문제를 자동으로 완화하는 기능을 제공합니다.

작동 방식

  1. 핫 파티션 감지
  2. 다른 파티션의 여유 용량을 핫 파티션에 재분배
  3. 필요 시 파티션 자동 분할
┌──────────────┐  ┌──────────────┐  ┌──────────────┐
│ 파티션 A     │  │ 파티션 B     │  │ 파티션 C     │
│ 사용: 200    │  │ 사용: 2800   │  │ 사용: 100    │
│ 한도: 1000   │  │ 한도: 1000   │  │ 한도: 1000   │
└──────────────┘  └──────────────┘  └──────────────┘
        │                │                 │
        └───────────────►│◄────────────────┘
                    Adaptive Capacity
                    B에 추가 용량 할당

한계

  • 즉각적이지 않음: 감지 및 조정에 시간 소요
  • 무한 확장 아님: 프로비저닝된 총 용량 내에서만 작동
  • 근본적 해결 아님: 설계 개선이 여전히 필요

시험 팁

시험에서 "Adaptive Capacity가 있으니 파티션 키 설계는 중요하지 않다"는 틀린 답변입니다.

실전 설계 패턴

패턴 1: 전자상거래 주문

테이블: Orders
파티션 키: customer_id (높은 카디널리티)
정렬 키: order_timestamp#order_id

조회 패턴:
- 특정 고객의 최근 주문: Query(pk=customer_id, sk begins_with "2026-01")
- 특정 주문 조회: GetItem(pk=customer_id, sk=timestamp#order_id)

패턴 2: 실시간 리더보드

문제: 전체 순위 조회 시 모든 파티션 스캔 필요

해결: GSI 활용
- 기본 테이블: pk=user_id, sk=game_id
- GSI: pk="GAME#game_id", sk=score (내림차순)
- 상위 100명 조회: Query(GSI, pk="GAME#001", Limit=100)

패턴 3: IoT 센서 데이터

문제: 수천 개 센서에서 초당 수만 건 데이터 유입

설계:
파티션 키: device_id#YYYY-MM-DD-HH (시간별 분산)
정렬 키: timestamp_ms

결과:
- 24시간 × 1000 센서 = 24,000 파티션으로 분산
- 개별 센서의 시간대별 조회 가능

SAA-C03 시험 출제 포인트

  1. 핫 파티션 원인: "낮은 카디널리티 또는 불균등한 접근 패턴"
  2. 쓰로틀링 해결: "파티션 키 재설계 또는 쓰기 샤딩"
  3. Adaptive Capacity: "자동 용량 재분배, 하지만 설계 대체 불가"
  4. 파티션 한도: "3,000 RCU, 1,000 WCU, 10GB/파티션"
  5. 복합 키 활용: "pk + sk로 세밀한 접근 패턴 지원"

시험 팁

시험 문제 예시: "DynamoDB 테이블에서 특정 날짜의 데이터 접근 시 쓰로틀링이 발생합니다. 파티션 키는 날짜(YYYY-MM-DD)입니다. 가장 적절한 해결책은?" → 정답: 파티션 키에 무작위 접미사를 추가하여 쓰기 샤딩 구현

자주 묻는 질문 (FAQ)

Q: 파티션 키를 나중에 변경할 수 있나요?

아니요. 파티션 키는 테이블 생성 후 변경할 수 없습니다. 새 테이블을 만들고 데이터를 마이그레이션해야 합니다.

Q: 정렬 키 없이도 테이블을 만들 수 있나요?

네. 파티션 키만 사용하는 단순 기본 키도 가능합니다. 하지만 복잡한 쿼리 패턴에는 정렬 키가 유용합니다.

Q: 샤딩 개수는 몇 개가 적당한가요?

예상 최대 쓰기 부하를 파티션당 1,000 WCU로 나눈 값 이상이어야 합니다. 예: 5,000 WCU 필요 → 최소 5개 샤드

Q: On-Demand 모드에서도 핫 파티션이 문제가 되나요?

네. On-Demand도 파티션당 한도가 있습니다. Adaptive Capacity가 작동하지만, 갑작스러운 부하 급증에는 대응이 늦을 수 있습니다.

Q: GSI도 핫 파티션 문제가 있나요?

네. GSI도 별도의 파티션 구조를 가지므로, GSI의 파티션 키 설계도 동일한 원칙을 따라야 합니다.

관련 글

참고 자료