Amazon DynamoDB가 무엇인지, NoSQL 모델의 작동 방식, 확장성 있고 저지연인 시스템 및 마이크로서비스를 위한 실용적 설계 패턴을 알아보세요.

Amazon DynamoDB는 AWS의 완전관리형 NoSQL 데이터베이스 서비스로, 사실상 모든 규모에서 일관되게 낮은 지연의 읽기·쓰기가 필요한 애플리케이션을 위해 설계되었습니다. “완전관리형”이란 AWS가 하드웨어 프로비저닝, 복제, 패치 및 많은 운영 작업을 처리한다는 뜻이며, 팀은 데이터베이스 서버 운영 대신 기능 배포에 집중할 수 있습니다.
핵심적으로 DynamoDB는 아이템(행)을 테이블 안에 저장하지만, 각 아이템은 유연한 속성을 가질 수 있습니다. 데이터 모델은 다음의 혼합으로 이해하는 것이 좋습니다:
팀은 관계형 조인이 잘 맞지 않는 워크로드에서 예측 가능한 성능과 더 간단한 운영을 원할 때 DynamoDB를 선택합니다. 마이크로서비스(각 서비스가 자신의 데이터를 소유), 트래픽이 버스트성인 서버리스 앱, 데이터 변경에 반응하는 이벤트 중심 시스템에 흔히 사용됩니다.
이 글은 빌딩 블록(테이블, 키, 인덱스), 접근 패턴에 맞춘 모델링(싱글 테이블 디자인 포함), 스케일링과 용량 모드, 그리고 변경 스트리밍을 이벤트 기반 아키텍처로 흘려보내는 실용적 패턴을 다룹니다.
DynamoDB는 몇 가지 단순한 빌딩 블록으로 구성되지만, 이들의 세부가 데이터 모델링과 요청 성능(및 비용)에 큰 영향을 줍니다.
테이블은 최상위 컨테이너입니다. 테이블의 각 레코드는 아이템(행 유사)이고, 각 아이템은 여러 속성(열 유사)으로 이루어져 있습니다.
관계형 데이터베이스와 달리 같은 테이블의 아이템은 동일한 속성을 공유할 필요가 없습니다. 한 아이템은 {status, total, customerId}를 가질 수 있고, 다른 아이템은 {status, shipmentTracking}을 포함할 수 있습니다—DynamoDB는 고정된 스키마를 요구하지 않습니다.
모든 아이템은 기본 키로 고유 식별되며, DynamoDB는 두 가지 유형을 지원합니다:
실무에서는 복합 키가 “고객의 모든 주문, 최신 순” 같은 그룹화된 접근 패턴을 가능하게 합니다.
Query는 기본 키(또는 인덱스 키)로 아이템을 읽습니다. 특정 파티션 키를 대상으로 하고 정렬 키 범위로 필터링할 수 있어 효율적이며 권장되는 경로입니다.
Scan은 전체 테이블(또는 인덱스)을 순회한 뒤 필터링합니다. 시작은 쉬우나 규모가 커지면 보통 느리고 비용이 높습니다.
초기에 느끼게 되는 몇 가지 제약:
이 기본 요소들이 이후에 나오는 접근 패턴, 인덱스 선택, 성능 특성을 결정합니다.
DynamoDB는 종종 키-값 스토어이자 도큐먼트 데이터베이스로 설명됩니다. 정확하지만, 각각이 일상적 설계에서 무엇을 의미하는지 아는 것이 도움이 됩니다.
핵심은 키로 데이터를 가져온다는 점입니다. 기본 키 값을 제공하면 DynamoDB는 단일 아이템을 반환합니다. 이 키 기반 조회가 많은 워크로드에서 예측 가능한 저지연 스토리지를 제공합니다.
동시에 아이템은 중첩 속성(맵과 리스트)을 포함할 수 있어 도큐먼트 DB처럼 동작합니다: 엄격한 스키마 없이 구조화된 페이로드를 저장할 수 있습니다.
아이템은 JSON과 유사한 데이터를 자연스럽게 매핑합니다:
profile.name, profile.address).엔터티를 보통 전체로 읽는 경우(사용자 프로필, 쇼핑 카트, 구성 묶음 등)에 특히 적합합니다.
DynamoDB는 서버 측 조인을 지원하지 않습니다. 앱에서 “주문 + 주문 항목 + 배송 상태”를 한 번의 읽기 경로로 가져와야 한다면, 종종 비정규화(denormalize) 합니다: 일부 속성을 여러 아이템에 복사하거나 작은 하위 구조를 아이템 내에 직접 임베드합니다.
비정규화는 쓰기 복잡성과 업데이트 팬아웃을 증가시킬 수 있습니다. 보상은 라운드 트립 감소와 더 빠른 읽기—확장 가능한 시스템에서 종종 중요한 경로입니다.
가장 빠른 DynamoDB 쿼리는 “이 파티션을 줘(besides optional range)”로 표현할 수 있는 쿼리입니다. 따라서 키 선택은 저장 방식뿐 아니라 어떻게 읽을지에 대한 설계입니다.
파티션 키는 아이템이 어느 물리적 파티션에 저장될지를 결정합니다. DynamoDB는 이 값을 해시하여 데이터와 트래픽을 분산합니다. 요청이 소수의 파티션 키 값에 집중되면, 테이블이 대부분 유휴 상태여도 “핫” 파티션이 생성되어 처리량 한계에 도달할 수 있습니다.
좋은 파티션 키:
"GLOBAL" 같은 상수)정렬 키가 있으면 동일 파티션 키를 갖는 항목들이 함께 저장되고 정렬 키로 정렬됩니다. 이를 통해 효율적인:
BETWEEN, begins_with)정렬 키를 구성하는 일반적 패턴은 TYPE#id나 TS#2025-12-22T10:00:00Z 같은 접두사 결합으로, 추가 테이블 없이 여러 쿼리 모양을 지원합니다.
PK = USER#\u003cid\u003e(GetItem)PK = USER#\u003cid\u003e, SK begins_with ORDER#(또는 SK = CREATED_AT#...)PK = DEVICE#\u003cid\u003e, SK = TS#\u003ctimestamp\u003e 와 BETWEEN을 사용한 시간 창 조회파티션 키가 가장 높은 볼륨의 쿼리와 정렬되면서 고르게 분산되면 일관되게 낮은 지연의 읽기·쓰기가 가능합니다. 그렇지 않다면 Scan, 필터, 추가 인덱스로 보완해야 하며, 이는 비용과 핫 키 위험을 증가시킵니다.
보조 인덱스는 기본 테이블의 기본 키 외에 대체 쿼리 경로를 제공합니다. 새로운 접근 패턴이 생길 때마다 테이블을 바꾸는 대신 그 항목들을 다른 키로 재키하는 인덱스를 추가할 수 있습니다.
**글로벌 보조 인덱스(GSI)**는 자체 파티션 키(및 선택적 정렬 키)를 가지며, 기본 테이블과 완전히 다를 수 있습니다. “글로벌”이라 불리는 이유는 모든 테이블 파티션에 걸쳐 존재하고 언제든지 추가·삭제할 수 있기 때문입니다. 예: 테이블이 orderId로 키되어 있을 때 customerId로 주문을 조회해야 하면 GSI를 사용합니다.
**로컬 보조 인덱스(LSI)**는 기본 테이블과 같은 파티션 키를 공유하지만 다른 정렬 키를 사용합니다. LSI는 테이블 생성 시에만 정의할 수 있습니다. 같은 엔터티 그룹(같은 파티션 키) 내에서 여러 정렬 순서가 필요할 때 유용합니다(예: 고객 주문을 createdAt별 또는 status별로 정렬해서 가져오기).
프로젝션은 인덱스에 어떤 속성을 저장할지 결정합니다:
기본 테이블에 대한 모든 쓰기는 하나 이상의 인덱스로의 쓰기를 유발할 수 있습니다. GSI가 많아지고 프로젝션이 넓어질수록 쓰기 비용과 용량 소비가 커집니다. 인덱스는 안정적인 접근 패턴에 맞춰 계획하고, 가능하면 투사되는 속성을 최소화하세요.
DynamoDB의 스케일링은 On-Demand 또는 Provisioned 용량 중 하나의 선택으로 시작합니다. 둘 다 매우 높은 처리량을 달성할 수 있지만 변화하는 트래픽에 대한 동작은 다릅니다.
On-Demand는 가장 단순합니다: 요청당 비용을 지불하며 DynamoDB가 자동으로 가변 부하를 수용합니다. 예측 불가한 트래픽, 초기 제품, 스파이크 워크로드에 적합합니다.
Provisioned는 용량 계획 방식입니다: 읽기와 쓰기 처리량을 명시(또는 오토스케일)하고 안정적인 사용량에서 더 예측 가능한 비용을 얻습니다. 수요를 예측할 수 있는 경우 더 저렴한 편입니다.
프로비저닝된 처리량은 다음으로 측정됩니다:
아이템 크기와 접근 패턴이 실제 비용을 결정합니다: 큰 아이템, 강한 일관성, 그리고 Scan은 용량을 빠르게 소진할 수 있습니다.
오토스케일링은 사용률 목표에 따라 RCUs/WCUs를 조정합니다. 이는 점진적 성장과 주기적 변동에 도움되지만 즉시 반응하지는 않습니다. 갑작스러운 스파이크는 용량이 충분히 빠르게 확장되지 않으면 쓰로틀링될 수 있고, 핫 파티션을 해결할 수는 없습니다.
**DynamoDB Accelerator(DAX)**는 인메모리 캐시로 반복적인 읽기의 지연을 줄이고 읽기 부하를 경감할 수 있습니다(예: 인기 상품 페이지, 세션 조회, 리더보드). 많은 클라이언트가 동일한 아이템을 반복적으로 요청하는 경우에 유용합니다. 쓰기 중심 패턴에는 도움이 되지 않으며, 키 설계를 대체하지도 않습니다.
DynamoDB는 읽기 보장과 지연/비용 사이의 선택을 허용하므로 각 작업에 대해 ‘정확성’이 무엇인지 명확히 하는 것이 중요합니다.
기본적으로 GetItem과 Query는 점진적 일관성 읽기를 사용합니다: 쓰기 직후 잠깐 오래된 값을 볼 수 있습니다. 피드·카탈로그 등 읽기 우선 뷰에는 보통 적합합니다.
단일 리전에서 기본 테이블에 대한 강한 일관성 읽기를 사용하면 마지막으로 확인된 쓰기를 볼 수 있음이 보장됩니다. 강한 일관성은 더 많은 읽기 용량을 소모하고 꼬리 지연을 증가시킬 수 있으므로 진짜로 중요한 읽기에만 사용하세요.
강한 일관성은 돌이킬 수 없는 작업을 방어하는 읽기에서 가치가 있습니다:
카운터의 경우 가장 안전한 접근은 보통 “강한 읽기 후 쓰기”가 아니라 원자적 업데이트(예: UpdateItem의 ADD)입니다. 이렇게 하면 증가치가 유실되지 않습니다.
DynamoDB 트랜잭션(TransactWriteItems, TransactGetItems)은 최대 25개 아이템에 대해 ACID를 제공합니다. 주문 작성과 재고 예약 같이 여러 아이템을 함께 업데이트해야 하거나 중간 상태를 허용할 수 없는 불변식을 강제할 때 유용합니다.
분산 시스템에서 재시도는 정상입니다. 재시도로 인해 효과가 중복되지 않도록 쓰기를 멱등하게 만드세요:
ConditionExpression(예: attribute_not_exists)로 고유성 강제DynamoDB에서의 정확성은 주로 올바른 일관성 수준을 선택하고 재시도로 인해 데이터가 훼손되지 않도록 작업을 설계하는 것에서 비롯됩니다.
DynamoDB는 테이블 데이터를 여러 물리적 파티션에 분산 저장합니다. 각 파티션은 읽기/쓰기 처리량과 저장 가능한 데이터 양에 제한이 있습니다. 파티션 키가 아이템의 위치를 결정하며, 너무 많은 요청이 동일한 파티션 키 값(또는 소수 값)에 집중되면 해당 파티션이 병목이 됩니다.
핫 파티션은 일반적으로 트래픽이 집중되도록 키를 잘못 선택했을 때 발생합니다: USER#1, TENANT#default, STATUS#OPEN 같은 “글로벌” 파티션 키나 모두가 현재 시간의 같은 버킷에 기록하는 시간 기반 패턴 등.
대개 다음을 관찰합니다:
ProvisionedThroughputExceededException)먼저 분산을 위한 설계를 하고 그 다음 쿼리 편의성을 고려하세요:
TENANT#\u003cid\u003e)ORDER#\u003cid\u003e#\u003cshard\u003e처럼 작은 랜덤/해시 접미사/접두사로 쓰기를 N개 샤드로 분산하고 필요할 때 샤드 전체를 쿼리METRIC#2025-12-22T10 등)예측 불가능한 스파이크에는 On-Demand 용량이 버스트를 흡수할 수 있습니다(서비스 한도 내). Provisioned 모드에서는 오토스케일링을 사용하고, 쓰로틀 시 동기화된 재시도가 스파이크를 증폭하지 않도록 클라이언트 측 지터가 있는 지수 백오프를 구현하세요.
DynamoDB 데이터 모델링은 ER 다이어그램이 아니라 접근 패턴에서 시작합니다. 필요한 쿼리들이 빠른 Query 연산으로 표현되도록 키를 설계하고, 나머지는 비동기적으로 처리하거나 회피합니다.
“싱글 테이블 디자인”은 여러 엔터티 타입(사용자, 주문, 메시지 등)을 하나의 테이블에 저장하고 일관된 키 규약으로 관련 데이터를 하나의 Query로 가져오게 하는 방식입니다. 이는 교차 엔터티 왕복을 줄이고 지연을 예측 가능하게 합니다.
일반적 접근은 복합 키 사용입니다:
PK는 논리적 파티션을 그룹화(예: USER#123)SK는 그룹 내 항목을 정렬(예: PROFILE, ORDER#2025-12-01, MSG#000123)이를 통해 “사용자에 대한 모든 것” 또는 “사용자의 주문만”을 정렬 키 접두사로 한 번에 가져올 수 있습니다.
그래프 같은 관계에는 인접 리스트가 잘 맞습니다: 간선을 아이템으로 저장합니다.
PK = USER#123, SK = FOLLOWS#USER#456역조회나 진정한 다대다를 위해서는 반전된 엣지 항목을 추가하거나 읽기 경로에 따라 GSI로 투사하면 됩니다.
이벤트와 메트릭에는 무한히 커지는 파티션을 피하기 위해 버킷화를 사용하세요:
PK = DEVICE#9#2025-12-22(장치+일)SK = TS#1734825600(타임스탬프)TTL로 오래된 포인트를 자동 만료시키고, 빠른 대시보드를 위해 시간별/일별 집계를 별도 항목으로 보관하세요.
더 깊은 키 규약 복습이 필요하면 /blog/partition-key-and-sort-key-design 를 참조하세요.
DynamoDB Streams는 내장된 변경 데이터 캡처(CDC) 피드입니다. 테이블에서 활성화하면 모든 삽입, 업데이트, 삭제에 대해 스트림 레코드가 생성되어 폴링 없이 다운스트림 소비자가 반응할 수 있습니다.
스트림 레코드는 키와 선택적으로 항목의 이전/새 이미지를 포함합니다(선택한 stream view type에 따라: keys only, new image, old image, both). 레코드는 샤드로 그룹화되며 순차적으로 읽습니다.
일반적인 구성은 DynamoDB Streams → AWS Lambda로, 각 레코드 배치가 함수를 트리거합니다. 커스텀 컨슈머나 분석/로깅 시스템으로 파이프하는 것도 가능합니다.
전형적 워크플로:
이렇게 하면 기본 테이블은 저지연 읽기/쓰기를 위해 최적화된 상태로 유지되고, 파생 작업은 비동기로 밀어낼 수 있습니다.
Streams는 샤드별 순서 처리(일반적으로 파티션 키와 상관관계가 있음)를 제공하지만 전역 순서는 보장하지 않습니다. 전달은 at-least-once이므로 중복이 발생할 수 있습니다.
안전하게 처리하려면:
이 보장들을 감안하면 Streams는 DynamoDB를 이벤트 기반 시스템의 견고한 백본으로 바꿀 수 있습니다.
DynamoDB는 리전 내 여러 가용 영역(AZ)에 데이터를 분산해 높은 가용성을 제공하도록 설계되었습니다. 실무에서의 신뢰성 향상은 명확한 백업 전략, 복제 옵션 이해, 적절한 모니터링에서 옵니다.
온디맨드 백업은 수동(또는 자동화) 스냅샷으로 마이그레이션 전, 릴리스 후, 대량 작업 전 같은 시점의 복구 지점을 만들 때 사용합니다.
**Point-in-time recovery(PITR)**는 변경을 연속 캡처해 보존 기간 내의 임의의 초 단위 시점으로 테이블을 복원할 수 있게 해줍니다. 실수로 삭제하거나 잘못된 쓰기가 발생했을 때의 안전망입니다.
다중 리전 복원력이나 사용자 근처의 저지연 읽기가 필요하면 Global Tables로 선택한 리전에 데이터를 복제할 수 있습니다. 이는 장애 조치 계획을 단순화하지만 교차 리전 복제 지연과 충돌 해결 고려사항을 도입하므로 쓰기 패턴과 아이템 소유권을 명확히 하세요.
최소한 다음에 대해 경고를 설정하세요:
이 신호들은 흔히 핫 파티션 문제, 불충분한 용량, 예상 밖 접근 패턴을 드러냅니다.
쓰로틀링 시, 먼저 원인이 되는 접근 패턴을 식별한 뒤 임시로 온디맨드로 전환하거나 프로비저닝 용량을 늘리고 핫 키 샤딩을 고려하세요.
부분적 장애나 오류 증가 시에는 비핵심 트래픽을 차단하고 지터 백오프로 재시도하며(예: 캐시된 읽기 제공) 테이블이 안정될 때까지 우아하게 실패 대응하세요.
DynamoDB 보안은 주로 누가 어떤 API 동작을, 어디서, 어떤 키에 대해 호출할 수 있는지를 조정하는 것입니다. 테이블이 여러 엔터티 타입(또는 여러 테넌트)을 담을 수 있으므로 접근 제어는 데이터 모델과 함께 설계해야 합니다.
dynamodb:GetItem, Query, PutItem 등 필요한 최소한의 동작으로 신원 기반 IAM 정책을 시작하고 특정 테이블 ARN으로 범위를 좁히세요.
더 세밀한 제어를 위해 dynamodb:LeadingKeys를 사용해 파티션 키 값으로 접근을 제한할 수 있습니다—서비스나 테넌트가 자신의 키스페이스만 읽기/쓰기해야 할 때 유용합니다.
DynamoDB는 기본적으로 AWS 소유 키나 고객 관리형 KMS 키로 데이터를 암호화합니다. 규정 준수가 필요하면 다음을 확인하세요:
전송 중 암호화는 AWS SDK가 기본적으로 HTTPS를 사용하므로 보장됩니다. 프록시에서 TLS를 종단할 경우 프록시와 DynamoDB 간 홉도 암호화되어 있는지 확인하세요.
VPC Gateway Endpoint를 사용해 트래픽을 AWS 네트워크에만 머물게 하고 엔드포인트 정책으로 접근을 제약하세요. 이를 NACL, 시큐리티 그룹, 라우팅과 함께 사용해 모든 것이 공용 인터넷으로 나가는 경로를 차단하세요.
공유 테이블의 경우 파티션 키에 테넌트 식별자를 포함하세요(예: TENANT#\u003cid\u003e) 그리고 dynamodb:LeadingKeys에 대한 IAM 조건으로 테넌트 격리를 시행하세요.
더 강한 격리가 필요하면 테넌트별 또는 환경별로 별도 테이블을 고려하고, 운영 단순성 및 비용 효율이 더 중요한 경우에만 공유 테이블을 사용하세요.
DynamoDB는 "정확하면 저렴하고, 모호하면 비싸다"는 특성이 있습니다. 비용 최적화는 접근 패턴을 명확히 하는 것에서 시작합니다.
청구서는 주로 다음에 의해 결정됩니다:
흔한 놀라움: 테이블에 대한 각 쓰기는 관련된 모든 GSI에도 쓰기되므로 "인덱스 하나 더"가 쓰기 비용을 배수로 늘릴 수 있습니다.
좋은 키 설계는 비싼 연산의 필요를 줄입니다. 자주 Scan을 사용한다면 읽고 버리는 데이터에 비용을 지불하는 것입니다.
권장:
드문 접근 패턴은 별도의 테이블, ETL 작업, 또는 캐시된 읽기 모델로 제공하는 것을 검토하세요.
세션, 임시 토큰, 중간 워크플로 상태 같은 단명 아이템에 TTL을 사용해 자동 삭제하세요. 이는 저장소를 줄이고 인덱스를 작게 유지하는 데 도움이 됩니다.
추가로 빌드업되는 데이터(이벤트, 로그)는 TTL과 정렬 키 설계를 결합해 “최근 것만” 쿼리하도록 해 차가운 히스토리를 자주 건드리지 않게 하세요.
프로비저닝 모드에서는 보수적인 베이스라인을 설정하고 실측 지표로 오토스케일링하세요. 온디맨드 모드에서는 비효율적 패턴(큰 아이템, 빈번한 채팅형 클라이언트)이 요청량을 끌어올리지 않는지 모니터링하세요.
Scan은 최후의 수단으로 취급하고 전체 테이블 처리가 정말 필요할 때는 비업무 시간에 페이지네이션과 백오프로 통제된 배치로 실행하세요.
DynamoDB는 애플리케이션을 잘 정의된 접근 패턴 집합으로 표현할 수 있고 높은 규모에서 일관된 저지연이 필요할 때 빛을 발합니다. 상위 쿼리들을 기본 키 기반으로 미리 설명할 수 있다면 운영 측면에서 가장 간단한 선택 중 하나입니다.
DynamoDB는 다음 상황에 강합니다:
다음이 핵심 요구사항이면 다른 선택을 고려하세요:
많은 팀은 운영의 ‘핫’ 읽기·쓰기를 DynamoDB에 두고 다음을 추가합니다:
접근 패턴과 싱글 테이블 규약을 검증하려면 속도가 중요합니다. 팀들은 종종 Koder.ai 같은 프로토타이핑 플랫폼으로 서비스·UI를 빠르게 만들고 실제 쿼리 경로가 드러나면 DynamoDB 키 설계를 반복합니다. 프로덕션 백엔드가 다르더라도 빠른 엔드-투-엔드 프로토타입은 어떤 쿼리가 Query가 되어야 하고 어떤 쿼리가 실수로 비싼 Scan이 될지를 드러냅니다.
검증할 것: (1) 최상위 쿼리가 키 기반으로 알려져 있는가, (2) 정확성 요구가 일관성 모델과 맞는가, (3) 예상 아이템 크기와 성장률을 이해하고 있는가, (4) 비용 모델(온디맨드 vs 프로비저닝 + 오토스케일링)이 예산에 맞는가.
DynamoDB는 AWS의 완전관리형 NoSQL 데이터베이스로, 매우 높은 스케일에서 일관되게 낮은 지연의 읽기/쓰기를 제공합니다. 팀은 ID로 조회하거나 소유자별 목록을 가져오거나 시간 범위 조회처럼 키 기반 접근 패턴을 정의할 수 있고 데이터베이스 인프라 관리를 피하고 싶을 때 DynamoDB를 선택합니다.
마이크로서비스, 서버리스 애플리케이션, 이벤트 기반 시스템에서 특히 흔히 사용됩니다.
테이블은 아이템(행과 유사)을 보관합니다. 각 아이템은 유연한 속성(열과 유사) 집합이며 중첩된 데이터를 포함할 수 있습니다.
DynamoDB는 한 요청으로 보통 “엔터티 전체”를 가져오는 경우에 잘 맞습니다. 아이템은 맵과 리스트(JSON과 유사한 구조)를 포함할 수 있기 때문입니다.
단일 파티션 키만 있는 경우(partition key)가 항목을 고유하게 식별합니다(단순 기본 키). **파티션 키 + 정렬 키(sort key)**를 사용하는 복합 기본 키는 동일한 파티션 키를 공유하는 여러 항목을 허용하면서 정렬 키로 구분되고 정렬된 상태를 유지합니다.
복합 키는 다음과 같은 패턴을 가능하게 합니다:
Query는 파티션 키(및 선택적으로 정렬 키 조건)를 지정할 수 있을 때 사용하세요. 이는 빠르고 확장 가능한 경로입니다.
Scan은 테이블(또는 인덱스) 전체를 읽고 나서 필터를 적용합니다. 보통 더 느리고 비용이 높기 때문에 정말 전체를 읽해야 할 때만 사용하세요.
자주 Scan을 사용한다면 키 또는 인덱스 설계가 조정되어야 한다는 신호입니다.
보조 인덱스는 대체 조회 경로를 제공합니다.
인덱스는 쓰기 시 인덱스로의 추가 쓰기를 발생시키므로 쓰기 비용이 증가합니다.
트래픽이 예측 불가능하거나 스파이크가 잦고 용량 관리를 원치 않으면 On-Demand를 선택하세요. 요청 단위로 비용을 지불합니다.
사용량이 안정적이고 예측 가능하여 비용을 더 통제하고 싶다면 Provisioned를 선택하고 오토스케일링을 적용하세요. 다만 급격한 스파이크에는 즉각 대응하지 못할 수 있습니다.
기본적으로 읽기는 Eventual Consistent(점진적 일관성) 입니다. 쓰기 직후 잠깐 오래된 값을 읽을 수 있습니다.
중요하고 최신 값이 반드시 필요하다면(예: 권한 확인, 워크플로 단계 전환) Strongly Consistent 읽기를 사용하세요. 강한 일관성은 더 많은 읽기 용량을 소모하고 지연의 테일을 늘릴 수 있습니다.
동시성 하에서 정확성을 보장하려면 읽기-수정-쓰기 루프 대신 **원자적 업데이트(예: UpdateItem의 ADD)**를 선호하세요.
트랜잭션(TransactWriteItems, TransactGetItems)은 최대 25개 항목에 대해 ACID 보장을 제공합니다.
주문 생성과 재고 예약 같이 여러 항목을 함께 업데이트해야 하거나 중간 상태를 허용할 수 없는 불변식을 강제할 때 사용하세요.
트랜잭션은 비용과 지연이 증가하므로 꼭 필요한 흐름에만 사용하세요.
핫 파티션은 너무 많은 요청이 동일한 파티션 키 값(또는 소수의 값)에 집중될 때 발생하며, 테이블 전체는 유휴 상태여도 해당 파티션만 쓰로틀링될 수 있습니다.
일반적인 완화 방법:
DynamoDB Streams를 활성화하면 삽입/업데이트/삭제에 대해 변경 피드(CDC)를 얻을 수 있습니다. 흔한 패턴은 Streams → Lambda로 각 레코드 배치가 함수 트리거되는 구성입니다.
설계 시 유의할 보장사항:
소비자는 아이덴포턴트(idempotent) 하게 설계하세요(키로 업서트, 조건부 쓰기, 처리된 이벤트 ID 추적 등).