데이터베이스 선택 기준
질문 기반 선택
1. 읽기 패턴?
- 많은 쿼리, 복잡한 조인 → RDS/Aurora
- 간단한 키-값 조회 → DynamoDB
- 분석 쿼리 → Redshift
2. 쓰기 패턴?
- 트랜잭션 필요 → RDS/Aurora
- 높은 쓰기 처리량 → DynamoDB
- 배치 쓰기 → S3 + Athena
3. 데이터 구조?
- 정형 데이터 (테이블) → RDS/Aurora
- 반정형 데이터 (JSON) → DynamoDB/DocumentDB
- 비정형 데이터 (파일) → S3
4. 확장성?
- 수직 확장 → RDS
- 수평 확장 → DynamoDB/Aurora
- 무제한 → S3
5. 비용?
- 저렴한 옵션 → RDS MySQL
- 성능 중시 → Aurora
- 서버리스 → DynamoDB On-Demand
관계형 데이터베이스
1. RDS (Relational Database Service)
엔진:
- MySQL, PostgreSQL, MariaDB
- Oracle, SQL Server
- Aurora (MySQL/PostgreSQL 호환)
사용 사례:
- 전통적인 애플리케이션
- ACID 트랜잭션 필요
- 복잡한 조인 쿼리
장점:
- 익숙한 SQL
- 자동 백업
- Multi-AZ 고가용성
단점:
- 수평 확장 제한
- 비교적 비쌈
-- 일반적인 사용 예시
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) UNIQUE,
name VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
total DECIMAL(10,2),
status VARCHAR(20),
FOREIGN KEY (user_id) REFERENCES users(id)
);
-- 복잡한 조인
SELECT u.name, COUNT(o.id) as order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id;
2. Aurora
특징:
- RDS보다 5배(MySQL) ~ 3배(PostgreSQL) 빠름
- 최대 15개 읽기 복제본
- 자동 스토리지 확장 (10GB → 128TB)
- 글로벌 데이터베이스
사용 사례:
- 고성능 필요
- 고가용성 중요
- 글로벌 서비스
비용:
- RDS보다 20% 비쌈
- 하지만 성능과 기능으로 정당화
# Aurora Serverless (자동 확장)
aws rds create-db-cluster \
--db-cluster-identifier my-aurora-cluster \
--engine aurora-mysql \
--engine-mode serverless \
--scaling-configuration MinCapacity=2,MaxCapacity=16,AutoPause=true
캐싱 데이터베이스
ElastiCache
엔진:
- Redis (추천)
- Memcached
사용 사례:
- 세션 저장
- 실시간 리더보드
- 빈번한 읽기 쿼리 캐싱
Redis 주요 기능:
import redis
r = redis.Redis(host='elasticache-endpoint', port=6379)
# 캐싱
def get_user(user_id):
# 캐시 확인
cached = r.get(f'user:{user_id}')
if cached:
return json.loads(cached)
# DB 조회
user = db.query(f"SELECT * FROM users WHERE id={user_id}")
# 캐시 저장 (1시간)
r.setex(f'user:{user_id}', 3600, json.dumps(user))
return user
# 리더보드 (Sorted Set)
r.zadd('leaderboard', {'player1': 1000, 'player2': 850})
top10 = r.zrevrange('leaderboard', 0, 9, withscores=True)
# Pub/Sub (실시간 알림)
r.publish('notifications', json.dumps({'type': 'new_message'}))
NoSQL 데이터베이스
1. DynamoDB
특징:
- 완전 관리형 NoSQL
- 한 자릿수 밀리초 지연시간
- 무제한 확장
- 서버리스
사용 사례:
- 모바일/웹 앱 백엔드
- IoT 데이터
- 게임 세션 데이터
- 높은 읽기/쓰기 처리량
데이터 모델:
# 테이블 설계
{
"UserId": "user123", # Partition Key
"GameId": "game456", # Sort Key
"Score": 1000,
"Level": 5,
"LastPlayed": "2024-11-19"
}
# 단일 항목 조회 (빠름)
response = table.get_item(
Key={'UserId': 'user123', 'GameId': 'game456'}
)
# Query (Partition Key 기반 - 효율적)
response = table.query(
KeyConditionExpression='UserId = :uid',
ExpressionAttributeValues={':uid': 'user123'}
)
# Scan (전체 스캔 - 비효율적, 피하기)
response = table.scan(
FilterExpression='Score > :score',
ExpressionAttributeValues={':score': 500}
)
RDS vs DynamoDB:
특성 | RDS | DynamoDB |
모델 | 관계형 (SQL) | 키-값 (NoSQL) |
조인 | 지원 | 없음 |
확장 | 수직 (제한적) | 수평 (무제한) |
트랜잭션 | ACID | 제한적 |
지연시간 | 수십 ms | 한 자릿수 ms |
비용 | 인스턴스 기반 | 처리량 기반 |
2. DocumentDB (MongoDB 호환)
사용 사례:
- MongoDB 마이그레이션
- 유연한 스키마
- JSON 문서 저장
// MongoDB 쿼리와 호환
db.users.insertOne({
name: "John Doe",
email: "john@example.com",
address: {
city: "Seoul",
country: "KR"
},
tags: ["premium", "active"]
});
db.users.find({ "address.city": "Seoul" });
3. Neptune (그래프 데이터베이스)
사용 사례:
- 소셜 네트워크
- 추천 엔진
- 지식 그래프
- 사기 탐지
사용자 관계:
(User1) -[FOLLOWS]-> (User2)
(User1) -[LIKES]-> (Post1)
(Post1) -[TAGGED]-> (User3)
쿼리: "User1의 친구가 좋아하는 게시물"
4. Keyspaces (Cassandra 호환)
사용 사례:
- IoT 시계열 데이터
- 대규모 분산 시스템
- Apache Cassandra 마이그레이션
전문 데이터베이스
1. QLDB (Quantum Ledger Database)
특징:
- 불변 원장
- 암호화 검증 가능
- 변경 이력 추적
사용 사례:
- 금융 거래 기록
- 공급망 추적
- 규제 준수
# 변경 불가능한 기록
qldb.execute_statement(
"INSERT INTO Transactions VALUE {'amount': 100, 'from': 'A', 'to': 'B'}"
)
# 모든 변경 이력 조회
history = qldb.execute_statement(
"SELECT * FROM history(Transactions) WHERE id = 'tx123'"
)
2. Timestream (시계열 데이터베이스)
사용 사례:
- IoT 센서 데이터
- 애플리케이션 메트릭
- DevOps 모니터링
-- 시계열 쿼리
SELECT
AVG(temperature) as avg_temp,
BIN(time, 1m) as minute
FROM sensor_data
WHERE measure_name = 'temperature'
AND time BETWEEN ago(1h) AND now()
GROUP BY BIN(time, 1m)
데이터 레이크 및 분석
S3 + Athena
사용 사례:
- 데이터 레이크
- 로그 분석
- 비정형 데이터 쿼리
-- S3에 저장된 로그 쿼리
CREATE EXTERNAL TABLE logs (
timestamp STRING,
level STRING,
message STRING
)
STORED AS PARQUET
LOCATION 's3://my-logs-bucket/';
SELECT
level,
COUNT(*) as count
FROM logs
WHERE timestamp > '2024-11-01'
GROUP BY level;
실전 선택 가이드
시나리오 1: 전자상거래 사이트
요구사항:
- 사용자, 제품, 주문 관리
- 복잡한 조인 쿼리
- ACID 트랜잭션
- 전 세계 사용자
솔루션:
[Aurora Global Database]
├─ Primary (ap-northeast-2)
│ └─ 읽기/쓰기
└─ Secondary (us-east-1)
└─ 읽기 전용
+ [ElastiCache Redis] ← 세션, 장바구니
+ [S3] ← 제품 이미지
시나리오 2: 모바일 게임
요구사항:
- 수백만 사용자
- 빠른 응답 (< 10ms)
- 높은 쓰기 처리량
- 글로벌 서비스
솔루션:
[DynamoDB Global Tables]
├─ ap-northeast-2
├─ us-east-1
└─ eu-west-1
테이블 설계:
- Players (UserId, PlayerData)
- GameSessions (UserId#Timestamp, SessionData)
- Leaderboards (GameId#Score, PlayerId)
시나리오 3: IoT 플랫폼
요구사항:
- 수천 개 센서
- 시계열 데이터
- 실시간 분석
- 장기 저장
솔루션:
[IoT Devices]
↓
[Kinesis Data Streams]
├─→ [Lambda] → [Timestream] ← 실시간 쿼리
└─→ [Kinesis Firehose] → [S3] → [Athena] ← 장기 분석
시나리오 4: 소셜 네트워크
요구사항:
- 사용자 관계 (팔로우, 친구)
- 추천 시스템
- 복잡한 관계 쿼리
솔루션:
[Neptune] ← 사용자 관계 그래프
[DynamoDB] ← 사용자 프로필, 게시물
[ElastiCache] ← 피드 캐싱
[S3] ← 이미지, 동영상
마이그레이션 전략
온프레미스 → AWS
1. 리프트 앤 시프트
MySQL on-premises → RDS MySQL
- 빠른 마이그레이션
- 최소 변경
2. 리팩토링
MySQL → Aurora
- 성능 향상
- 고가용성 기능 활용
3. 재설계
Oracle → DynamoDB
- 클라우드 네이티브
- 서버리스
- 최대 성능/확장성
Database Migration Service (DMS)
[Source DB]
↓ DMS
[Target DB]
지원:
- 동종 마이그레이션 (MySQL → MySQL)
- 이기종 마이그레이션 (Oracle → Aurora)
- 지속적 복제
비용 최적화
RDS/Aurora
1. Reserved Instances (1-3년)
- 최대 69% 할인
2. Aurora Serverless
- 간헐적 워크로드
- 개발/테스트 환경
3. 읽기 복제본 활용
- 읽기 부하 분산
- 보고서/분석 쿼리 분리
DynamoDB
1. On-Demand vs Provisioned
- 예측 가능 → Provisioned + Auto Scaling
- 불규칙 → On-Demand
2. Reserved Capacity
- 1-3년 약정
- 최대 77% 할인
3. TTL 활용
- 오래된 데이터 자동 삭제
- 스토리지 비용 절감
ElastiCache
1. Reserved Nodes
- 1-3년 약정
- 최대 55% 할인
2. 적절한 노드 크기
- 메모리 사용률 모니터링
- 다운사이징 검토
모니터링 및 최적화
RDS/Aurora
# Slow Query 확인
aws rds download-db-log-file-portion \
--db-instance-identifier mydb \
--log-file-name slowquery/mysql-slowquery.log
# Performance Insights
aws pi get-resource-metrics \
--service-type RDS \
--identifier db-ABCD1234 \
--metric-queries '[{
"Metric": "db.load.avg",
"GroupBy": {"Group": "db.sql"}
}]'
DynamoDB
# 용량 사용률 확인
aws cloudwatch get-metric-statistics \
--namespace AWS/DynamoDB \
--metric-name ConsumedReadCapacityUnits \
--dimensions Name=TableName,Value=MyTable \
--start-time 2024-11-19T00:00:00Z \
--end-time 2024-11-19T23:59:59Z \
--period 3600 \
--statistics Sum
최종 선택 플로우차트
데이터베이스 선택:
관계형 데이터?
├─ Yes → 성능 중요?
│ ├─ Yes → Aurora
│ └─ No → RDS (MySQL/PostgreSQL)
│
└─ No → 데이터 타입?
├─ 키-값 → DynamoDB
├─ 문서 (JSON) → DocumentDB
├─ 그래프 → Neptune
├─ 시계열 → Timestream
├─ 원장 → QLDB
└─ 분석 → S3 + Athena
캐싱 필요? → ElastiCache (Redis)
AWS는 모든 워크로드에 최적화된 데이터베이스를 제공
핵심 원칙
- 워크로드 이해 - 읽기/쓰기 패턴 분석
- 올바른 도구 - 각 데이터베이스의 강점 활용
- 시작은 간단하게 - 나중에 마이그레이션 가능
- 지속적 최적화 - 모니터링 및 조정
일반적 조합
- 웹 앱: Aurora + ElastiCache + S3
- 모바일 앱: DynamoDB + S3
- IoT: Timestream + S3
- 분석: S3 + Athena + Redshift
Share article