본문으로 건너뛰기
aws검색
데이터베이스와 분석

DynamoDB 와 ElastiCache (키 설계, 용량 모드, Valkey 캐시)

DynamoDB 의 파티션 키와 정렬 키 설계, 단일 테이블 설계, 온디맨드와 프로비저닝 용량, GSI, 글로벌 테이블(2025-06 GA 다중 리전 강한 일관성), 그리고 ElastiCache 의 Valkey 엔진과 서버리스, 캐시 패턴과 흔한 장애를 정리합니다.

DynamoDB파티션 키글로벌 테이블ElastiCacheValkey2026-10 기준, 약 7분상태 표시 설명

DynamoDB 의 핵심 개념

DynamoDB 는 서버리스 키-값, 문서 데이터베이스입니다. 테이블 크기에 상관없이 한 자릿수 ms 응답을 내는 대신, 어떻게 읽을지를 먼저 정하고 키를 설계해야 합니다. 관계형처럼 "일단 넣고 나중에 아무렇게나 질의" 하는 방식은 맞지 않습니다.

개념뜻
파티션 키 (PK)데이터를 파티션에 나누는 해시 키. 값이 고르게 퍼져야 함
정렬 키 (SK)같은 PK 안에서 정렬. 범위 질의(begins_with, between) 가능
항목한 행. 최대 400 KB
GSI다른 키로 읽기 위한 전역 보조 인덱스. 비동기로 갱신, 테이블당 기본 20 개
LSI같은 PK, 다른 SK. 테이블 만들 때만 생성, 최대 5 개

접근 패턴부터 쓴다

주문 서비스라면 먼저 "고객의 최근 주문 20 개", "주문 번호로 주문 상세", "상태가 배송 중인 주문" 같은 접근 패턴을 적고, 그에 맞게 키를 고릅니다.

PKSK속성
CUST#c-1001ORDER#2026-10-20T09:12:00#o-778status, amount
ORDER#o-778ITEM#1sku, qty
ORDER#o-778METAcustomerId, createdAt
import boto3
from boto3.dynamodb.conditions import Key
table = boto3.resource("dynamodb", region_name="ap-northeast-2").Table("orders")
resp = table.query(
    KeyConditionExpression=Key("PK").eq("CUST#c-1001") & Key("SK").begins_with("ORDER#"),
    ScanIndexForward=False, Limit=20,
)

Scan 은 테이블 전체를 읽어서 느리고 비쌉니다. 운영 코드에서 Scan 이 보이면 키 설계를 다시 봅니다.

핫 파티션

파티션 하나는 초당 3,000 RCU, 1,000 WCU 가 한도입니다. 특정 키(인기 상품, 오늘 날짜)에 쓰기가 몰리면 테이블 전체 용량이 남아도 ProvisionedThroughputExceededException 이나 throttling 이 납니다. 키에 접미사를 붙여 분산(write sharding)하거나, CloudWatch Contributor Insights 로 어떤 키가 뜨거운지 먼저 찾습니다.

용량 모드

모드과금맞는 곳
온디맨드읽기, 쓰기 요청 단위예측이 어렵거나 새 서비스. 대부분의 기본값
프로비저닝 + 오토 스케일링초당 용량(RCU, WCU)을 시간당꾸준하고 예측 가능한 대량 트래픽. 예약 용량 할인

2024-11 에 온디맨드 처리량 단가가 절반으로 내려가면서 "기본은 온디맨드" 가 더 확실해졌습니다. 온디맨드에도 테이블별 최대 처리량을 걸 수 있어서 버그로 인한 비용 폭주를 막을 수 있습니다. 2025-12 의 Database Savings Plans 는 DynamoDB 온디맨드 처리량에 최대 18%, 프로비저닝 용량에 최대 12% 할인을 줍니다.

일관성, 트랜잭션, 글로벌 테이블

  • 읽기는 기본이 최종 일관성이고, ConsistentRead=True 로 강한 일관성 읽기를 할 수 있습니다(RCU 두 배, GSI 는 불가).
  • TransactWriteItems 로 최대 100 개 항목을 원자적으로 씁니다.
  • 글로벌 테이블은 여러 리전에 같은 테이블을 두고 양방향으로 복제합니다. 기본은 비동기 복제(마지막 쓰기 우선)이고, 2025-06 에 다중 리전 강한 일관성(MRSC) 이 GA 되어 세 리전 구성에서 어느 리전에서 읽어도 최신 값을 보장하는 모드를 고를 수 있습니다. MRSC 는 쓰기 지연이 늘어나니 꼭 필요한 테이블에만 씁니다.

운영 기능

  • TTL: 만료 시각 속성을 정하면 무료로 지워 줍니다(즉시가 아니라 보통 며칠 안).
  • Streams: 변경 이벤트를 Lambda 로 받아 이벤트 기반 처리, 집계 테이블 갱신에 씁니다.
  • 특정 시점 복구(PITR): 최근 최대 35 일 안의 초 단위 시점으로 새 테이블을 복원합니다. 복구 기간을 1 일부터 35 일 사이로 줄일 수 있습니다.
  • S3 내보내기, 제로 ETL: 분석은 운영 테이블을 스캔하지 말고 S3 내보내기나 Redshift, OpenSearch 제로 ETL 통합으로 합니다.
  • 삭제 보호를 운영 테이블에 켭니다.

ElastiCache

ElastiCache 는 관리형 인메모리 캐시입니다. 엔진은 Valkey, Redis OSS, Memcached 중에서 고릅니다.

Valkey

Valkey 는 Redis 의 라이선스 변경 뒤 Linux Foundation 아래에서 이어진 오픈 소스 포크입니다. ElastiCache 는 2024-10 부터 Valkey 를 지원하고, Valkey 가격을 서버리스는 Redis OSS 보다 33%, 노드 기반은 최대 20% 낮게 매깁니다. 명령과 프로토콜이 호환되므로 대부분의 Redis 클라이언트를 그대로 쓰고, 기존 Redis OSS 클러스터는 다운타임 없이 Valkey 로 엔진을 바꿀 수 있습니다. 새로 만든다면 Valkey 가 기본 선택입니다.

서버리스와 노드 기반

방식특징
ElastiCache Serverless용량 계획 없음. 저장 GB-시간과 처리 단위(ECPU)로 과금. Valkey 는 최소 100 MB 부터, 월 6 USD 수준에서 시작
노드 기반 클러스터노드 유형과 샤드, 복제본 수를 직접 정함. 꾸준한 대량 트래픽에 단가가 유리, 예약 노드와 Savings Plans 적용

내구성이 필요한 기본 저장소로 쓰려면 ElastiCache 대신 MemoryDB 를 봅니다. 트랜잭션 로그를 여러 AZ 에 남깁니다.

캐시 패턴

def get_product(pid):
    key = f"product:{pid}"
    v = cache.get(key)
    if v is not None:
        return json.loads(v)
    row = db.fetch_product(pid)              # 캐시 미스면 DB 에서
    cache.set(key, json.dumps(row), ex=300 + random.randint(0, 60))  # TTL 에 흔들림을 더해 동시 만료 방지
    return row
  • 지연 로딩(cache-aside) 이 기본입니다. 쓸 때는 DB 를 고친 뒤 캐시 키를 지웁니다.
  • TTL 에 무작위 값을 더해 한꺼번에 만료되며 DB 에 몰리는 캐시 스탬피드를 막습니다.
  • 큰 값(수 MB)과 거대한 키 하나에 몰리는 패턴은 지연과 네트워크 대역폭 문제를 부릅니다.

증상, 원인, 해결

증상원인해결
지연 급증, EngineCPUUtilization 높음KEYS *, 큰 SMEMBERS 같은 O(N) 명령SCAN 계열로 바꾸고 느린 로그 확인
키가 사라짐메모리 가득 차서 축출(eviction)Evictions 지표, maxmemory-policy, 노드 확장
연결 실패보안 그룹, 전송 중 암호화 설정 불일치클라이언트 TLS 설정, 6379 포트 허용
장애 조치 뒤 쓰기 실패클라이언트가 옛 주 노드 IP 를 캐시구성 엔드포인트 사용, 클러스터 모드 지원 클라이언트

자주 하는 실수

  • DynamoDB 를 관계형처럼 설계: 테이블을 엔터티마다 쪼개고 조인을 애플리케이션에서 하면 요청 수와 비용이 폭증합니다.
  • GSI 쓰기 용량 부족: GSI 가 throttling 되면 본 테이블 쓰기도 막힙니다.
  • 캐시를 유일한 저장소로 씀: ElastiCache 는 재시작과 축출로 데이터를 잃을 수 있습니다.
  • 캐시 무효화 없이 TTL 만 김: 오래된 값이 길게 보입니다. 쓰기 경로에서 키를 지웁니다.

이 문서에서