AWS RDS vs DynamoDB 차이: 데이터베이스 선택 기준

2026. 6. 8. 09:12Cloud/AWS

반응형

새 서비스를 설계할 때 "DB는 뭘로 하지?"라는 질문이 나옵니다. AWS에서 가장 많이 비교되는 조합이 RDS와 DynamoDB입니다. 둘 다 관리형 서비스지만, 데이터 모델, 확장 방식, 비용 구조가 근본적으로 다릅니다. 잘못된 선택은 6개월 뒤 마이그레이션이라는 비용으로 돌아옵니다.

요약

기준 RDS DynamoDB
데이터 모델 관계형 (테이블, 행, 열, JOIN) Key-Value / Document (스키마리스)
쿼리 SQL (복잡한 JOIN, 서브쿼리 가능) 기본키 기반 조회, 제한적 쿼리
확장 방식 수직 확장 (인스턴스 크기 변경) 수평 확장 (자동 파티셔닝)
지연 시간 수 ms~수십 ms (쿼리 복잡도에 따라) 한 자릿수 ms (일관적)
운영 인스턴스 관리, 패치, 백업 스케줄 설정 서버리스, 인프라 관리 불필요
비용 모델 인스턴스 시간 + 스토리지 + I/O 요청당 과금 또는 프로비저닝 용량
트랜잭션 ACID 완전 지원 제한적 트랜잭션 (100개 항목, 4MB 이내)
추천 상황 복잡한 관계, 리포팅, 정합성이 중요한 시스템 대규모 트래픽, 단순 접근 패턴, 서버리스 아키텍처

1. 왜 이 비교가 필요한가

"관계형이 익숙하니까 RDS"로 결정하거나, "서버리스가 트렌드니까 DynamoDB"로 결정하는 경우가 많습니다. 두 가지 모두 위험한 접근입니다.

실무에서 흔히 발생하는 시나리오:

  • RDS를 선택했는데 트래픽이 급증: 이벤트 기간에 초당 수만 건의 쓰기가 발생하면, RDS는 인스턴스 크기를 올려야 합니다. 수직 확장에는 한계가 있고, Read Replica 추가에도 시간이 걸립니다.
  • DynamoDB를 선택했는데 복잡한 조회가 필요: "지난달 주문 중 환불된 건의 상품별 매출을 집계해줘"라는 요구가 들어오면, DynamoDB에서는 이 쿼리를 직접 수행할 수 없습니다.

데이터베이스 선택은 되돌리기 어려운 결정입니다. 데이터 모델, 접근 패턴, 확장 요구사항을 기준으로 판단해야 합니다.

2. RDS란

Amazon RDS(Relational Database Service)는 관계형 데이터베이스를 관리형으로 제공하는 서비스입니다.

핵심 특성

특성 설명
지원 엔진 MySQL, PostgreSQL, MariaDB, Oracle, SQL Server, Aurora
데이터 모델 테이블 기반, 정규화된 스키마, 외래 키, JOIN
확장 방식 수직 확장 (인스턴스 변경) + Read Replica (읽기 분산)
가용성 Multi-AZ 배포 (자동 장애 조치)
백업 자동 백업 (최대 35일) + 수동 스냅샷
최대 스토리지 128TB (Aurora), 64TB (기타 엔진)

RDS가 잘하는 것

  • 복잡한 관계 표현: 사용자, 주문, 상품, 결제, 배송 같은 엔터티 간 관계를 외래 키와 JOIN으로 표현
  • ACID 트랜잭션: "결제 성공 → 재고 차감 → 주문 상태 변경"을 하나의 트랜잭션으로 보장
  • 유연한 쿼리: 사전에 정의하지 않은 조건으로도 데이터를 조회 가능 (Ad-hoc Query)
  • 리포팅/분석: GROUP BY, HAVING, 윈도우 함수 등으로 집계 분석

3. DynamoDB란

Amazon DynamoDB는 완전 관리형 NoSQL 데이터베이스로, Key-Value와 Document 모델을 지원합니다.

핵심 특성

특성 설명
데이터 모델 Key-Value / Document (JSON 유사 구조)
스키마 파티션 키(PK)와 정렬 키(SK)만 필수, 나머지 속성은 자유
확장 방식 자동 수평 확장 (파티셔닝)
지연 시간 한 자릿수 밀리초 (규모와 무관하게 일관)
용량 모드 On-demand (요청당 과금) / Provisioned (용량 사전 지정)
글로벌 테이블 Multi-Region 복제 지원 (Active-Active)
최대 항목 크기 400KB

DynamoDB가 잘하는 것

  • 대규모 트래픽 처리: 초당 수백만 건의 요청을 한 자릿수 ms로 처리
  • 예측 가능한 성능: 데이터가 10GB든 10TB든 응답 시간이 일정
  • 서버리스 통합: Lambda + API Gateway + DynamoDB 조합으로 인프라 관리 제로
  • 글로벌 복제: Global Tables로 Multi-Region Active-Active 구현

4. 구조 비교

RDS vs DynamoDB 아키텍처 비교
RDS vs DynamoDB 아키텍처 비교

RDS 아키텍처

클라이언트 → RDS Endpoint → Primary Instance (Read/Write)
                          → Read Replica (Read Only) × N개
                          → Standby Instance (Multi-AZ 장애 조치용)
  • 하나의 Primary 인스턴스가 모든 쓰기를 처리합니다.
  • Read Replica로 읽기 부하를 분산할 수 있지만, 쓰기 확장은 인스턴스 크기에 의존합니다.
  • Multi-AZ 배포 시 Standby 인스턴스가 자동 장애 조치를 담당합니다.

DynamoDB 아키텍처

클라이언트 → DynamoDB Endpoint → 파티션 1 (PK hash 기반 분산)
                               → 파티션 2
                               → 파티션 N (자동 분할)
  • 파티션 키의 해시값으로 데이터가 자동 분산됩니다.
  • 트래픽이 늘면 파티션이 자동으로 분할(split)됩니다.
  • 클라이언트는 파티션 구조를 알 필요 없이 단일 엔드포인트로 접근합니다.

5. 데이터 모델 차이

RDS vs DynamoDB 데이터 모델 비교
RDS vs DynamoDB 데이터 모델 비교

RDS: 정규화된 관계 모델

-- 사용자 테이블
CREATE TABLE users (
  user_id INT PRIMARY KEY,
  name VARCHAR(100),
  email VARCHAR(255) UNIQUE
);

-- 주문 테이블 (사용자와 1:N 관계)
CREATE TABLE orders (
  order_id INT PRIMARY KEY,
  user_id INT REFERENCES users(user_id),
  total_amount DECIMAL(10,2),
  status VARCHAR(20),
  created_at TIMESTAMP
);

-- 주문 상품 테이블 (주문과 N:M 관계)
CREATE TABLE order_items (
  order_id INT REFERENCES orders(order_id),
  product_id INT REFERENCES products(product_id),
  quantity INT,
  price DECIMAL(10,2)
);

-- 복잡한 조회: 특정 사용자의 최근 주문과 상품 정보
SELECT u.name, o.order_id, p.product_name, oi.quantity
FROM users u
JOIN orders o ON u.user_id = o.user_id
JOIN order_items oi ON o.order_id = oi.order_id
JOIN products p ON oi.product_id = p.product_id
WHERE u.user_id = 123
ORDER BY o.created_at DESC
LIMIT 10;

데이터를 정규화해서 중복을 제거하고, 필요할 때 JOIN으로 조합합니다. 쿼리 패턴을 사전에 확정하지 않아도 됩니다.

DynamoDB: 접근 패턴 기반 모델

// 단일 테이블 설계 (Single Table Design)
// PK: USER#123, SK: ORDER#2024-01-15#001
{
  "PK": "USER#123",
  "SK": "ORDER#2026-01-15#001",
  "order_id": "001",
  "total_amount": 45000,
  "status": "delivered",
  "items": [
    {"product_id": "P001", "name": "키보드", "quantity": 1, "price": 35000},
    {"product_id": "P002", "name": "마우스패드", "quantity": 2, "price": 5000}
  ]
}

접근 패턴(Access Pattern)을 먼저 정의하고, 그에 맞게 테이블을 설계합니다. "이 사용자의 최근 주문 10건을 조회"라는 패턴이 확정되어 있다면 위 구조로 한 번의 쿼리로 모든 정보를 가져올 수 있습니다.

핵심 차이

관점 RDS DynamoDB
설계 시작점 데이터 구조(엔터티, 관계)부터 설계 접근 패턴(쿼리 요구사항)부터 설계
스키마 변경 ALTER TABLE로 컬럼 추가/변경 (마이그레이션 필요) 새 속성을 그냥 추가 (스키마리스)
데이터 중복 정규화로 최소화 성능을 위해 의도적으로 비정규화
쿼리 유연성 높음 (임의 조건 조합 가능) 낮음 (사전 설계된 패턴만 효율적)

6. 확장성 차이

RDS: 수직 확장 + 읽기 분산

확장 방법 설명 한계
인스턴스 업그레이드 db.m6g.large → db.m6g.4xlarge 최대 인스턴스 크기 제한, 변경 시 다운타임 발생 가능
Read Replica 읽기 부하 분산 (최대 15개) 쓰기는 분산 불가, 복제 지연(Replication Lag) 발생
Aurora Auto Scaling Reader 인스턴스 자동 추가/제거 쓰기 확장은 여전히 단일 Writer

RDS에서 쓰기 성능의 한계는 단일 Primary 인스턴스의 CPU/메모리/IOPS입니다. 이를 넘어서면 샤딩을 직접 구현하거나 아키텍처를 변경해야 합니다.

DynamoDB: 자동 수평 확장

확장 방법 설명 한계
자동 파티셔닝 트래픽 증가 시 파티션 자동 분할 핫 파티션(Hot Partition) 발생 시 스로틀링
On-demand 모드 트래픽 규모에 관계없이 자동 대응 이전 피크의 2배까지 즉시 확장, 그 이상은 점진적
Auto Scaling Provisioned 모드에서 자동 용량 조정 스케일링 반응 시간 1~2분 소요

DynamoDB는 파티션 키만 잘 설계하면 사실상 무한에 가까운 수평 확장이 가능합니다. 다만 특정 파티션 키에 트래픽이 집중되는 핫 파티션 문제를 주의해야 합니다.

확장성 판단 기준

상황 권장 선택
읽기 위주, 쓰기가 초당 수천 건 이하 RDS (Read Replica로 충분)
쓰기가 초당 수만 건 이상 DynamoDB
트래픽 패턴이 예측 불가 (갑자기 10배 증가) DynamoDB On-demand
데이터 크기가 수 TB 이상 DynamoDB (RDS는 스토리지 한계 존재)

7. 비용 비교

7.1 RDS 비용 구조

RDS는 인스턴스를 실행하는 동안 시간당 비용이 발생합니다.

항목 예시 (us-east-1, MySQL)
인스턴스 db.m6g.large: 약 $0.152/시간 (~$111/월)
스토리지 (gp3) $0.08/GB/월
Multi-AZ 인스턴스 비용 2배
백업 스토리지 무료 (DB 크기까지), 초과 시 $0.095/GB/월
데이터 전송 리전 내 무료, 리전 간 $0.02/GB

예시: db.m6g.large, Multi-AZ, 100GB gp3 스토리지

  • 인스턴스: $0.152 × 2 (Multi-AZ) × 730시간 = $221.92/월
  • 스토리지: $0.08 × 100GB × 2 (Multi-AZ) = $16/월
  • 합계: 약 $238/월 (트래픽이 없어도 고정 비용 발생)

7.2 DynamoDB 비용 구조

DynamoDB는 두 가지 과금 모드를 제공합니다.

On-demand 모드 (us-east-1, Standard 테이블):

항목 단가
쓰기 요청 $0.625 / 100만 WRU
읽기 요청 $0.125 / 100만 RRU
스토리지 $0.25/GB/월 (첫 25GB 무료)

Provisioned 모드 (us-east-1):

항목 단가
쓰기 용량 $0.00065/WCU/시간 (~$0.4745/WCU/월)
읽기 용량 $0.00013/RCU/시간 (~$0.0949/RCU/월)
스토리지 $0.25/GB/월 (첫 25GB 무료)

7.3 비용 시나리오 비교

시나리오 A: 소규모 SaaS (일 100만 요청, 50GB 데이터)

항목 RDS (db.m6g.large, Multi-AZ) DynamoDB (On-demand)
컴퓨팅/요청 $221.92 (고정) 쓰기 50만 × $0.625/100만 = $0.31, 읽기 50만 × $0.125/100만 = $0.06
스토리지 $16 $0.25 × 25GB = $6.25 (25GB 무료 적용)
월 합계 ~$238 ~$7

이 시나리오에서는 DynamoDB가 훨씬 저렴합니다. 트래픽이 적을 때 On-demand 모드의 강점이 드러납니다.

시나리오 B: 대규모 서비스 (일 1억 요청, 500GB 데이터, 안정적 트래픽)

항목 RDS (db.m6g.4xlarge, Multi-AZ) DynamoDB (Provisioned)
컴퓨팅/용량 ~$890 (인스턴스) WCU 1000 × $0.4745 + RCU 2000 × $0.0949 = $664.30
스토리지 $80 $0.25 × 475GB = $118.75
월 합계 ~$970 ~$783

대규모에서도 DynamoDB가 비용 효율적일 수 있지만, 차이가 줄어듭니다. 다만 GSI(Global Secondary Index)를 추가하면 DynamoDB 비용이 빠르게 증가합니다.

검증 필요
위 가격은 us-east-1 기준이며, 리전별로 상이할 수 있습니다. 실제 비용은 AWS Pricing Calculator로 확인해야 합니다. DynamoDB On-demand 모드의 쓰기 단가($0.625/100만 WRU)와 읽기 단가($0.125/100만 RRU)는 2026년 6월 기준입니다.

7.4 비용 판단 핵심

상황 비용 유리한 선택
트래픽이 적거나 불규칙 DynamoDB On-demand (사용한 만큼만 지불)
트래픽이 안정적이고 예측 가능 DynamoDB Provisioned 또는 RDS Reserved Instance
복잡한 쿼리 + 리포팅 필요 RDS (별도 분석 도구 없이 SQL로 해결)
GSI가 3개 이상 필요한 접근 패턴 RDS가 비용 면에서 유리할 수 있음

8. 운영 복잡도 차이

RDS vs DynamoDB 운영 비교
RDS vs DynamoDB 운영 비교
기준 RDS DynamoDB
인스턴스 관리 인스턴스 타입 선택, 크기 변경 필요 없음 (서버리스)
OS/엔진 패치 유지보수 윈도우 설정 필요 없음
백업 자동 백업 설정 + 보존 기간 관리 PITR 활성화만 하면 자동
스케일링 수동 또는 Auto Scaling 설정 자동 (On-demand) 또는 Auto Scaling
모니터링 CPU, 메모리, 디스크, 커넥션 수 등 읽기/쓰기 용량, 스로틀링, 지연 시간
장애 복구 Multi-AZ 설정 시 자동 Failover (30~60초) 자동 (사용자 개입 불필요)
연결 관리 Connection Pool 크기 관리 필요 HTTP 기반, 연결 풀 불필요
스키마 변경 DDL 실행, 마이그레이션 도구 사용 스키마리스 (속성 자유 추가)

RDS 운영 시 주의점

  • 커넥션 고갈: 애플리케이션이 많아지면 DB 커넥션이 부족해질 수 있습니다. RDS Proxy를 사용하면 커넥션 풀링을 관리할 수 있습니다.
  • 패치 다운타임: 엔진 패치 시 수 초~수 분의 다운타임이 발생할 수 있습니다. Multi-AZ 환경에서는 Failover로 최소화합니다.
  • 스토리지 Full: 디스크가 가득 차면 DB가 중지됩니다. Auto Scaling Storage를 활성화하거나 CloudWatch 알람을 설정해야 합니다.

DynamoDB 운영 시 주의점

  • 핫 파티션: 특정 파티션 키에 트래픽이 집중되면 스로틀링이 발생합니다. 파티션 키 설계가 핵심입니다.
  • GSI 비용 폭증: GSI를 추가할 때마다 쓰기 비용이 배로 증가합니다. GSI 설계를 신중하게 해야 합니다.
  • 항목 크기 제한: 단일 항목 최대 400KB. 큰 데이터는 S3에 저장하고 참조만 보관해야 합니다.

9. 트랜잭션과 일관성

기준 RDS DynamoDB
ACID 트랜잭션 완전 지원 (BEGIN, COMMIT, ROLLBACK) 제한적 (TransactWriteItems: 최대 100개 항목, 4MB)
격리 수준 Serializable, Repeatable Read 등 선택 가능 항목 단위 직렬화
일관성 강한 일관성 (Strong Consistency) Eventually Consistent (기본) / Strongly Consistent (선택)
외래 키 제약 지원 미지원 (애플리케이션에서 관리)

RDS 트랜잭션 예시

BEGIN;
  UPDATE accounts SET balance = balance - 50000 WHERE account_id = 'A001';
  UPDATE accounts SET balance = balance + 50000 WHERE account_id = 'A002';
  INSERT INTO transactions (from_id, to_id, amount, created_at)
    VALUES ('A001', 'A002', 50000, NOW());
COMMIT;

세 작업이 모두 성공하거나 모두 롤백됩니다. 부분 실패가 불가능합니다.

DynamoDB 트랜잭션 예시

dynamodb.transact_write_items(
    TransactItems=[
        {
            'Update': {
                'TableName': 'Accounts',
                'Key': {'PK': {'S': 'ACCOUNT#A001'}},
                'UpdateExpression': 'SET balance = balance - :amount',
                'ExpressionAttributeValues': {':amount': {'N': '50000'}}
            }
        },
        {
            'Update': {
                'TableName': 'Accounts',
                'Key': {'PK': {'S': 'ACCOUNT#A002'}},
                'UpdateExpression': 'SET balance = balance + :amount',
                'ExpressionAttributeValues': {':amount': {'N': '50000'}}
            }
        }
    ]
)

DynamoDB도 트랜잭션을 지원하지만, 최대 100개 항목 또는 4MB 이내라는 제약이 있습니다. 또한 트랜잭션 요청은 일반 요청 대비 2배의 용량을 소비합니다.

판단 기준

  • 금융 거래, 재고 관리, 결제: 복잡한 트랜잭션과 강한 일관성이 필수 → RDS
  • 소셜 미디어 좋아요, 조회수, 세션 데이터: 약간의 비일관성 허용 가능 → DynamoDB

10. 선택 기준

10.1 의사결정 플로우

RDS vs DynamoDB 선택 기준 플로우
RDS vs DynamoDB 선택 기준 플로우
어떤 데이터를 저장하는가?
│
├── 엔터티 간 복잡한 관계가 있는가? (1:N, N:M, JOIN 필요)
│   ├── Yes → 접근 패턴이 확정되어 있는가?
│   │         ├── Yes + 대규모 트래픽 → DynamoDB (Single Table Design)
│   │         └── No 또는 다양한 Ad-hoc 쿼리 필요 → RDS
│   └── No → 단순 Key-Value 조회 위주인가?
│            ├── Yes → DynamoDB
│            └── 집계/리포팅도 필요 → RDS
│
├── 확장 요구사항은?
│   ├── 초당 수만 건 이상 쓰기 → DynamoDB
│   ├── 예측 불가한 트래픽 스파이크 → DynamoDB On-demand
│   └── 안정적인 트래픽, 수천 건 이하 → RDS
│
└── 운영 환경 제약은?
    ├── 서버리스 아키텍처 (Lambda 기반) → DynamoDB
    ├── 기존 SQL 기반 애플리케이션 마이그레이션 → RDS
    └── 팀에 DynamoDB 설계 경험이 없음 → RDS (학습 비용 고려)

10.2 RDS를 선택해야 하는 경우

상황 이유
복잡한 관계와 JOIN이 필수 DynamoDB에서는 JOIN을 애플리케이션에서 구현해야 함
Ad-hoc 쿼리가 빈번 "어떤 조건으로 데이터를 볼지" 사전에 확정할 수 없는 환경
리포팅/분석 기능 필요 SQL 기반 집계, GROUP BY, 서브쿼리 활용
ACID 트랜잭션이 복잡 다수 테이블에 걸친 복잡한 트랜잭션
기존 SQL 기반 시스템 마이그레이션 코드 변경 최소화

10.3 DynamoDB를 선택해야 하는 경우

상황 이유
한 자릿수 ms 응답이 필수 규모와 무관하게 일관된 지연 시간 보장
초당 수만~수백만 건 처리 자동 수평 확장으로 대응
접근 패턴이 명확하고 제한적 PK/SK 기반 조회로 충분한 경우
서버리스 아키텍처 Lambda와 자연스럽게 통합
트래픽 변동이 극심 On-demand 모드로 유휴 비용 제거
글로벌 서비스 Global Tables로 Multi-Region 복제

11. 실무 예시

사례 1: 전자상거래 플랫폼

문제: 상품 카탈로그, 사용자 정보, 주문, 결제를 하나의 DB로 처리하려고 합니다.

설계 판단:

이 시나리오에서는 "모든 것을 하나의 DB로"가 아니라, 도메인별로 적합한 DB를 선택하는 것이 운영 환경에서의 일반적인 접근입니다.

도메인 선택 이유
사용자/주문/결제 RDS (PostgreSQL) 관계가 복잡하고, 트랜잭션 정합성 필수
상품 카탈로그 DynamoDB 상품 조회가 PK 기반, 읽기 트래픽 대량, 속성이 상품마다 다름
장바구니/세션 DynamoDB TTL로 자동 만료, 높은 쓰기 빈도, 정합성 요구 낮음
주문 이력 조회 DynamoDB 사용자별 최근 주문 N건 조회 패턴이 명확

결과: RDS는 핵심 비즈니스 로직(결제, 재고)을 담당하고, DynamoDB는 높은 트래픽과 단순 접근 패턴을 처리합니다. 하나의 서비스에서 두 DB를 함께 사용하는 것은 AWS 환경에서 흔한 패턴입니다.

사례 2: IoT 센서 데이터 수집

문제: 10만 대의 IoT 장치에서 5초마다 센서 데이터를 전송합니다. 초당 20,000건의 쓰기가 발생합니다.

설계 판단:

  • RDS로는 초당 20,000건 쓰기를 감당하기 어렵습니다. 최대 인스턴스를 사용해도 디스크 IOPS 한계에 부딪힙니다.
  • DynamoDB On-demand 모드로 설정하면 별도 용량 계획 없이 자동 확장됩니다.
// DynamoDB 테이블 설계
{
  "PK": "DEVICE#sensor-001",
  "SK": "2026-06-08T10:30:05Z",
  "temperature": 23.5,
  "humidity": 65,
  "battery": 87
}
  • 파티션 키: 장치 ID (10만 개의 고유 키로 트래픽 분산)
  • 정렬 키: 타임스탬프 (시간순 조회 가능)
  • TTL 설정: 30일 이후 자동 삭제 (비용 절감)

이 시나리오에서 RDS를 선택했다면 샤딩을 직접 구현하거나 Amazon Timestream 같은 시계열 DB를 별도로 검토해야 합니다.

사례 3: 사내 ERP 시스템

문제: 직원 50명이 사용하는 ERP 시스템. 인사, 급여, 프로젝트 관리 기능이 필요합니다.

설계 판단:

  • 트래픽이 낮고 (동시 사용자 50명 이하), 데이터 간 관계가 복잡합니다.
  • "특정 부서의 지난 분기 프로젝트별 인건비를 산출해줘" 같은 Ad-hoc 쿼리가 빈번합니다.
  • 이 상황에서 DynamoDB를 선택하면 모든 집계를 애플리케이션 레벨에서 구현해야 합니다.

결론: RDS (PostgreSQL)가 적합합니다. 트래픽이 낮으므로 가장 작은 인스턴스로도 충분하고, SQL의 유연성이 운영 효율을 높입니다.

12. 함께 사용하는 패턴

실무에서는 RDS와 DynamoDB를 병행하는 경우가 많습니다.

패턴 설명
CQRS 쓰기는 RDS에서 처리, 읽기 최적화 뷰는 DynamoDB에 비정규화 저장
캐시 계층 RDS가 원본, DynamoDB(또는 ElastiCache)가 자주 조회되는 데이터 캐시
이벤트 소싱 RDS에 핵심 상태 저장, DynamoDB Streams로 이벤트 전파
도메인 분리 트랜잭션 필수 도메인은 RDS, 고처리량 도메인은 DynamoDB
Tip
하나의 서비스에서 RDS와 DynamoDB를 함께 사용할 때, DynamoDB를 "읽기 최적화 저장소"로 활용하는 CQRS 패턴은 높은 읽기 성능과 데이터 정합성을 동시에 확보할 수 있습니다. RDS의 변경 이벤트를 Lambda로 받아서 DynamoDB에 비정규화된 뷰를 동기화하는 구조입니다.

13. 자주 하는 실수

  1. "RDS가 익숙하니까"로 선택하는 것: 초당 수만 건의 쓰기가 예상되는데 팀이 SQL에 익숙하다는 이유로 RDS를 선택하면, 6개월 뒤 성능 한계에 부딪힙니다. 접근 패턴이 단순하면 DynamoDB 학습 비용을 감수할 가치가 있습니다.
  2. DynamoDB에서 RDS처럼 쓰는 것: DynamoDB를 관계형 모델로 설계하면(테이블을 여러 개 만들고 애플리케이션에서 JOIN), RDS보다 느리고 비싸고 복잡해집니다. Single Table Design을 제대로 학습해야 합니다.
  3. GSI를 과도하게 추가하는 것: DynamoDB에서 새로운 쿼리 패턴이 필요할 때마다 GSI를 추가하면 쓰기 비용이 배로 증가합니다. GSI 3개 이상이면 설계를 재검토하는 것이 좋습니다.
  4. RDS 인스턴스 크기를 과대 선정하는 것: 초기에 "혹시 모르니까" 큰 인스턴스를 선택하면 매월 불필요한 비용이 발생합니다. 작게 시작하고 CloudWatch 메트릭을 보며 올리는 것이 운영 비용을 줄입니다.
  5. DynamoDB에서 Scan을 자주 사용하는 것: Scan은 테이블 전체를 읽으므로 비용과 성능 모두에 악영향을 줍니다. Scan이 필요하다면 접근 패턴 설계를 다시 검토해야 합니다.

14. 정리

  • RDS는 복잡한 관계, ACID 트랜잭션, 유연한 쿼리가 필요한 시스템에 적합합니다.
  • DynamoDB는 대규모 트래픽, 한 자릿수 ms 응답, 서버리스 아키텍처에 적합합니다.
  • "어떤 것이 더 좋다"가 아니라, 데이터 모델과 접근 패턴에 따라 선택이 달라집니다.
  • 실무에서는 하나의 서비스 내에서도 도메인별로 RDS와 DynamoDB를 병행하는 것이 일반적입니다.
  • 가장 중요한 판단 기준은 접근 패턴이 사전에 확정 가능한지, 그리고 엔터티 간 관계를 JOIN으로 표현해야 하는지입니다.

참고 문서

반응형