coredot.today
DynamoDB 완전 정복: Amazon이 논문 한 편으로 시작한 NoSQL 혁명
블로그로 돌아가기
DynamoDBAWSNoSQL데이터베이스Dynamo서버리스

DynamoDB 완전 정복: Amazon이 논문 한 편으로 시작한 NoSQL 혁명

2007년 Amazon 내부 논문에서 시작해, 전 세계 10조 건 이상의 요청을 하루에 처리하는 서비스가 되기까지. Dynamo 논문의 핵심 아이디어, Single Table Design의 철학, 그리고 실전 사례와 주의점을 풀어본다.

코어닷투데이2026-01-2327

들어가며: 크리스마스에 장바구니가 사라졌다

2004년 크리스마스 시즌, Amazon.com에서 최악의 시나리오가 벌어졌다. 주문이 폭주하면서 관계형 데이터베이스가 한계에 도달했다. 일부 사용자의 장바구니 데이터가 유실됐고, 주문 처리가 지연됐다. 연중 가장 중요한 매출 시즌에.

문제의 핵심: Amazon의 핵심 서비스들(장바구니, 세션 관리, 추천) — 은 단순한 키-값 조회가 대부분이었다. "이 사용자의 장바구니를 가져와라." 이 작업에 관계형 DB의 복잡한 조인(JOIN), 트랜잭션, 스키마가 필요한가? 오히려 이 복잡성이 확장을 가로막는 병목이 되고 있었다.

Amazon의 엔지니어들은 근본적인 질문을 던졌다:

"모든 데이터가 정말 관계형 모델이 필요한가? 아니면 더 단순하고 더 확장 가능한 모델이 있는가?"

이 질문에서 시작된 프로젝트가 Dynamo이고, 그 아이디어를 서비스로 만든 것이 DynamoDB다.


1. Dynamo 논문: NoSQL 혁명의 불씨 (2007)

역사를 바꾼 논문

2007년 10월, Amazon의 엔지니어 Giuseppe DeCandia 등 7명이 ACM SOSP(운영체제 원리 심포지엄)에서 논문을 발표했다:

"Dynamo: Amazon's Highly Available Key-value Store"

이 논문은 컴퓨터 과학 역사에서 가장 영향력 있는 시스템 논문 중 하나가 됐다. 인용 횟수 5,000회 이상. 이 한 편의 논문이 NoSQL 운동 전체의 도화선이 됐다.

Dynamo 논문의 핵심 아이디어

Dynamo는 전통적 데이터베이스의 상식을 뒤집었다:

전통적 RDBMS의 철학
일관성(Consistency)이 최우선
ACID 트랜잭션 보장
스키마를 미리 정의
수직 확장 (더 큰 서버)
복잡한 쿼리 (JOIN, 서브쿼리)
Dynamo의 철학
가용성(Availability)이 최우선
최종적 일관성(Eventual Consistency)
스키마 없음 (Schemaless)
수평 확장 (서버를 더 추가)
단순한 키-값 조회만

CAP 정리와의 관계:

UC Berkeley의 Eric Brewer가 2000년에 제안한 CAP 정리(CAP Theorem): 분산 시스템은 일관성(Consistency), 가용성(Availability), 파티션 허용성(Partition Tolerance)세 가지를 동시에 만족할 수 없다.

네트워크 파티션은 분산 시스템에서 피할 수 없으므로, 결국 C(일관성)와 A(가용성) 중 하나를 선택해야 한다. 전통적 RDBMS는 C를 선택했고, Dynamo는 A를 선택했다.

💡
Amazon의 비즈니스 판단: "고객이 장바구니에 상품을 담았는데 시스템이 응답하지 않는 것"(가용성 실패)과 "장바구니에 잠시 이전 버전이 보이는 것"(일관성 실패) 중 비즈니스에 더 치명적인 것은 전자다. 그래서 Amazon은 가용성을 선택했다. 기술적 선택이 아니라 비즈니스 선택이었다.

Dynamo의 핵심 기술

논문에서 소개된 기술들은 이후 모든 분산 데이터베이스의 교과서가 됐다:

1. 일관된 해싱(Consistent Hashing): 데이터를 여러 노드에 균등하게 분배하는 방법. 노드가 추가되거나 제거되어도 최소한의 데이터만 이동한다.

2. 벡터 클럭(Vector Clocks): 여러 노드에서 동시에 데이터가 수정됐을 때 충돌을 감지하고 해결하는 방법.

3. 쿼럼 기반 복제: N개 노드에 복제하고, W개 노드에 쓰기 성공하면 쓰기 완료, R개 노드에서 읽으면 읽기 완료. W+R > N이면 일관성을 보장하지만, Amazon은 W+R ≤ N으로 설정하여 가용성을 우선시했다.

4. 가십 프로토콜(Gossip Protocol): 노드들이 서로의 상태 정보를 "소문"처럼 퍼뜨려 장애를 감지하는 분산 프로토콜.

NoSQL 운동의 도화선

Dynamo 논문의 영향으로 탄생한 프로젝트들:

프로젝트시기Dynamo에서 가져온 것
Apache Cassandra2008 (Facebook)일관된 해싱, 가십 프로토콜
Apache HBase2008분산 스토리지 모델
Riak2009Dynamo 아키텍처 거의 그대로
Voldemort2009 (LinkedIn)키-값 모델, 일관된 해싱
DynamoDB2012 (AWS)Dynamo + SimpleDB의 결합

2. DynamoDB: Dynamo의 아이디어를 서비스로

Dynamo ≠ DynamoDB

혼동하기 쉽지만, Dynamo(2007 내부 시스템)와 DynamoDB(2012 AWS 서비스)는 다르다. DynamoDB는 Dynamo의 아이디어에 SimpleDB(AWS의 초기 NoSQL 서비스)의 교훈을 결합하여 새로 만든 것이다.

2012년 1월 출시 시 Werner Vogels(Amazon CTO)는 이렇게 말했다:

"DynamoDB가 목표로 하는 것은 분명하다. 개발자가 규모에 대해 걱정하지 않는 것."

DynamoDB의 핵심 특성

<10ms 한 자릿수 밀리초 지연 규모에 상관없이 일정
무한 확장 용량 제한 없음 테이블 크기 무제한
완전 관리형 서버 관리 제로 패치, 백업, 스케일링 자동
서버리스 온디맨드 모드 요청이 없으면 비용 0원

DynamoDB는 RDS와 근본적으로 다른 서비스다:

특성RDS (관계형)DynamoDB (NoSQL)
데이터 모델테이블, 행, 열, 관계키-값 + 문서
스키마고정 (ALTER TABLE)유연 (항목마다 다를 수 있음)
쿼리SQL (JOIN, GROUP BY 등)키 기반 조회, Scan, Query
스케일링수직 (인스턴스 크기)수평 (자동 파티셔닝)
지연 시간수~수십 ms일정하게 < 10ms
관리인스턴스 선택 필요완전 서버리스 가능
트랜잭션완전한 ACID제한적 트랜잭션 (2018~)
적합한 경우복잡한 관계, 분석 쿼리대규모 읽기/쓰기, 예측 가능한 접근 패턴

3. DynamoDB의 데이터 모델

기본 구조: 테이블, 항목, 속성

hljs language-json
{
  "PK": "USER#u123",
  "SK": "PROFILE",
  "name": "김개발",
  "email": "kim@example.com",
  "plan": "pro",
  "created_at": "2026-01-15"
}
  • 테이블(Table): 항목의 컬렉션. RDS의 테이블과 비슷하지만, 고정 스키마가 없다
  • 항목(Item): 하나의 레코드. RDS의 행(row). 최대 400KB
  • 속성(Attribute): 데이터 필드. RDS의 열(column). 항목마다 다를 수 있다

파티션 키와 정렬 키: DynamoDB를 이해하는 열쇠

DynamoDB에서 가장 중요한 설계 결정은 키 구조다.

파티션 키(Partition Key, PK): 데이터가 물리적으로 어떤 파티션에 저장될지 결정한다. 해시 함수를 통해 데이터를 여러 파티션에 분배한다.

정렬 키(Sort Key, SK): 같은 파티션 내에서 데이터를 정렬한다. 범위 쿼리(BETWEEN, begins_with)가 가능해진다.

파티션 키로 데이터가 분배되는 방식
DynamoDB 테이블 PK로 해시 → 파티션 자동 분배
파티션 A PK: USER#u001 ~ USER#u500
파티션 B PK: USER#u501 ~ USER#u999
파티션 C PK: USER#u1000 ~ ...
⚠️
핫 파티션 함정: 파티션 키가 편중되면 특정 파티션에 트래픽이 집중되어 스로틀링이 발생한다. 예: PK를 date로 설정하면, 오늘 날짜의 파티션에 모든 쓰기가 몰린다. 카디널리티가 높은 키(사용자 ID, 주문 ID 등)를 파티션 키로 선택하라.

4. Single Table Design: DynamoDB의 고급 설계 철학

"테이블 하나에 모든 것을"

관계형 DB에서는 엔티티별로 테이블을 만든다: users, orders, products, reviews. DynamoDB에서는 하나의 테이블에 모든 엔티티를 저장하는 패턴이 권장된다. 이것이 Single Table Design(단일 테이블 설계)이다.

AWS의 DynamoDB 수석 에반젤리스트 Rick Houlihan이 2018~2019년 re:Invent에서 이 개념을 집중적으로 소개하며 커뮤니티에 퍼졌다. 그의 세션은 DynamoDB 역사상 가장 많이 시청된 강연 중 하나다.

왜 단일 테이블인가?

관계형 DB의 접근: 데이터를 정규화하여 여러 테이블에 분리하고, 쿼리 시 JOIN으로 합친다.

hljs language-sql
-- RDS: 사용자와 주문을 JOIN으로 조회
SELECT u.name, o.order_id, o.total
FROM users u
JOIN orders o ON u.id = o.user_id
WHERE u.id = 'u123';

DynamoDB의 접근: JOIN이 없다. 대신, 관련 데이터를 같은 파티션에 미리 모아놓는다.

PK              SK                  속성들
─────────────── ─────────────────── ──────────────
USER#u123       PROFILE             name: "김개발", email: ...
USER#u123       ORDER#2026-03-01    total: 45000, items: [...]
USER#u123       ORDER#2026-03-15    total: 12000, items: [...]
USER#u123       ORDER#2026-03-18    total: 89000, items: [...]

이제 PK = USER#u123으로 Query하면, 프로필과 모든 주문이 한 번의 조회로, 한 자릿수 ms로 반환된다. JOIN이 없으므로 테이블 크기가 커져도 성능이 일정하다.

Single Table Design의 장단점

장점
관련 데이터를 한 번의 쿼리로 조회 (1 RTT)
규모에 상관없이 일정한 성능
테이블 관리 포인트 최소화
DynamoDB 비용 구조에 최적화
트랜잭션 범위가 같은 파티션 내로 한정
단점
설계가 어렵다 (접근 패턴을 미리 알아야 함)
데이터를 보면 직관적이지 않다
새로운 접근 패턴 추가가 어려울 수 있음
팀의 학습 곡선이 가파르다
분석 쿼리(ad-hoc)에 부적합
💡
실전 조언 — Alex DeBrie의 접근법: "The DynamoDB Book"의 저자 Alex DeBrie는 Single Table Design을 "모든 프로젝트에 무조건 적용할 필요는 없다"고 조언한다. 접근 패턴이 명확하고 고정된 서비스(사용자 프로필, 주문 관리)에는 최적이지만, 접근 패턴이 자주 바뀌는 초기 스타트업에서는 오히려 부담이 될 수 있다. 처음에는 심플하게 시작하고, 성능 요구가 커지면 최적화하라.

5. DynamoDB 보안: 사고와 교훈

공개된 DynamoDB 테이블 사고

S3 버킷 공개 사고만큼 대중적이지는 않지만, DynamoDB 관련 보안 사고도 발생했다:

2019년 — Capital One 사고의 DynamoDB 연결고리: 이전 RDS 글에서 다룬 Capital One 사고에서, 공격자는 탈취한 IAM 자격증명으로 S3뿐 아니라 DynamoDB 테이블에도 접근했다. 문제는 DynamoDB 테이블에 과도한 IAM 권한이 부여되어 있었던 것.

2020~2022년 — IAM 키 유출을 통한 데이터 탈취: GitHub에 실수로 커밋된 AWS IAM 키를 통해 DynamoDB 테이블의 데이터가 유출되는 사례가 다수 보고됐다. DynamoDB는 네트워크 격리(VPC 엔드포인트)와 IAM 정책이 유일한 방어선이므로, IAM 키 관리가 핵심이다.

보안 모범 사례

  • 최소 권한 IAM 정책: dynamodb:GetItem만 필요하면 dynamodb:*를 주지 마라
  • VPC 엔드포인트: DynamoDB 트래픽이 인터넷을 거치지 않도록 VPC Gateway Endpoint 사용
  • 저장 시 암호화: 기본 활성화 (AWS 관리 키 또는 KMS 키)
  • IAM 키를 코드에 넣지 마라: EC2/Lambda의 IAM 역할 사용, Secrets Manager 활용
  • DynamoDB Streams + Lambda로 감사 로그: 데이터 변경을 실시간 모니터링

6. DynamoDB 비용 모델: 두 가지 선택

온디맨드 vs 프로비저닝

온디맨드 (On-Demand)프로비저닝 (Provisioned)
과금요청 건당초당 읽기/쓰기 용량(RCU/WCU)에 따라
스케일링자동 (즉시)수동 또는 Auto Scaling
트래픽이 없을 때비용 0원 (저장 비용만)프로비저닝된 용량에 과금
비용 수준요청당 비용 높음단가 낮지만 유휴 비용 발생
적합한 경우트래픽 예측 어려움, 초기 서비스트래픽 예측 가능, 대규모
비용 전략: 새 서비스는 온디맨드로 시작하라. 트래픽 패턴이 파악되면 프로비저닝 + Auto Scaling으로 전환하면 비용을 최대 70~80% 절감할 수 있다. Reserved Capacity(1~3년 약정)를 추가하면 더 줄일 수 있다.

비용 최적화 핵심

  • GSI는 별도 비용: 글로벌 보조 인덱스(GSI)는 별도의 읽기/쓰기 용량을 소비한다. 불필요한 GSI 삭제
  • 항목 크기 최소화: DynamoDB는 항목 크기에 비례하여 용량을 소비. 큰 데이터는 S3에 저장하고 DynamoDB에는 참조만
  • TTL 활용: Time-to-Live로 오래된 데이터를 자동 삭제. 저장 비용 절감
  • DAX 캐싱: DynamoDB Accelerator(DAX)로 자주 읽는 데이터를 인메모리 캐시. 읽기 비용 대폭 절감 + 마이크로초 응답

7. DynamoDB + Lambda: 서버리스의 황금 조합

DynamoDB와 Lambda는 AWS 서버리스 아키텍처의 황금 조합이다. 둘 다 서버 관리 불필요, 자동 스케일링, 사용량 과금.

전형적인 서버리스 API

클라이언트
API Gateway
Lambda 함수
DynamoDB

이 전체 스택에서 관리해야 할 서버: 0대. 트래픽이 없으면 비용: 거의 0원. 트래픽이 폭증하면: 자동 확장.

DynamoDB Streams + Lambda: 이벤트 기반 처리

DynamoDB Streams는 테이블의 모든 변경(추가/수정/삭제)을 실시간 이벤트 스트림으로 제공한다. Lambda를 트리거로 연결하면:

  • 주문이 생성되면 → Lambda가 확인 이메일 발송
  • 사용자 프로필이 변경되면 → Lambda가 검색 인덱스 업데이트
  • 재고가 임계값 이하로 떨어지면 → Lambda가 알림 발송

8. 실제 사례

Amazon.com: DynamoDB의 원조 사용자

Amazon.com 자체가 DynamoDB의 가장 큰 사용자다. 프라임데이(Prime Day)에 초당 수천만 건의 요청을 DynamoDB가 처리한다. 2023년 프라임데이에 DynamoDB는 피크 초당 1억 2,600만 건의 요청을 처리했다고 AWS가 발표했다.

Lyft: 실시간 위치 추적

수백만 대의 차량 위치를 실시간으로 추적하는 Lyft는 DynamoDB를 사용한다. 차량 위치 업데이트는 초당 수백만 건이며, 각 업데이트에 한 자릿수 ms 응답이 필요하다 — DynamoDB의 완벽한 유스케이스다.

Samsung: SmartThings IoT

이전 글들에서 반복 등장한 Samsung SmartThings. 수억 대의 IoT 기기 상태 데이터를 DynamoDB에 저장한다. 기기 상태 조회가 대부분이고, 한 자릿수 ms 응답이 필수.

Duolingo: 학습 진행 상태

4억 명 이상의 사용자의 학습 진행 상태, 스트릭(streak), 리더보드 데이터를 DynamoDB에 저장한다.

한국 기업 사례

  • 배달의민족: 실시간 주문 상태 관리, 라이더 위치 추적에 DynamoDB 활용
  • 쿠팡: 장바구니, 세션 관리에 DynamoDB 사용. Amazon의 원래 유스케이스와 동일
  • 토스: 사용자 세션, 알림 상태 등 고속 키-값 조회에 DynamoDB

9. DynamoDB를 쓰지 말아야 할 때

DynamoDB는 만능이 아니다. 이런 경우에는 RDS/Aurora가 더 적합하다:

상황이유대안
복잡한 JOIN이 필요DynamoDB에 JOIN 없음RDS, Aurora
접근 패턴이 불확실Single Table Design은 패턴이 확정돼야 함PostgreSQL
분석/리포팅 쿼리ad-hoc 쿼리에 부적합Athena, Redshift
강력한 트랜잭션제한적 트랜잭션만 지원Aurora, PostgreSQL
관계형 데이터 모델정규화된 관계를 표현하기 어려움RDS
비용 예측이 어려움잘못된 키 설계 시 비용 폭증 가능RDS (인스턴스 고정비)
💡
최종 판단 기준: DynamoDB를 선택할지 고민될 때: "내 핵심 쿼리가 PK(+SK)로 표현 가능한가?" 답이 "예"면 DynamoDB, "아니오"면 RDS. 사용자 프로필, 세션, 장바구니, IoT 상태 → DynamoDB. 주문-상품-카테고리 복합 분석 → RDS.

마치며: 모든 데이터가 관계형일 필요는 없다

Dynamo 논문에서 시작된 혁명의 핵심 메시지는 이것이다:

"데이터의 특성에 맞는 데이터베이스를 선택하라."

2000년대까지는 "데이터베이스 = 관계형 DB"였다. 모든 데이터를 MySQL이나 Oracle에 넣었다. 하지만 모든 데이터가 복잡한 관계를 가지는 것은 아니다. 장바구니는 키-값이고, 로그는 시계열이고, 소셜 그래프는 그래프 DB가 적합하다.

이것을 다중 모델 아키텍처(Polyglot Persistence) 라고 부른다. Martin Fowler가 2011년에 정리한 이 개념은 2026년 현재 대부분의 기업이 실천하고 있다:

  • 사용자 인증, 결제 → 관계형 DB (RDS/Aurora)
  • 세션, 캐시, 실시간 상태 → DynamoDB
  • 검색 → OpenSearch (Elasticsearch)
  • 파일 → S3
  • 분석 → Redshift, Athena
  • AI 벡터 → pgvector, OpenSearch

코어닷투데이의 AI 서비스에서도 이 패턴은 동일하다. AI 모델 메타데이터는 DynamoDB에 빠르게 조회하고, 학습 데이터는 S3에 저장하고, 사용자 관계 데이터는 Aurora에 보관한다. 각 데이터의 특성에 맞는 최적의 저장소를 선택하는 것 — 그것이 Dynamo 논문이 18년 전에 던진 질문의 현재 답이다.