72장. 통합 흐름 — 데이터 계층을 우리 서비스에 끼우기
이 장에서 말하고자 하는 것
Part 11에서 우리는 데이터 계층의 모든 부품을 다뤘다.
- 61장. AWS DB 지형
- 62장. RDS
- 63장. Multi-AZ
- 64장. Read Replica
- 65장. Aurora
- 66장. DynamoDB 사고방식
- 67장. DynamoDB 인덱스
- 68장. DynamoDB 용량 모델
- 69장. ElastiCache
- 70장. Database per Service
- 71장. 백업 · 복구 · DR
이 장은 그 부품들을 우리 MSA 척추에 끼워 한 그림으로 정리한다.
1. 전체 그림
[사용자]
↓
[CloudFront]
↓
[API Gateway]
↓ VPC Link
[Private ALB]
├─ /api/orders/* → ECS "orders" → RDS orders-db (Multi-AZ)
├─ /api/users/* → ECS "users" → RDS users-db (Multi-AZ)
├─ /api/payments/* → ECS "payments" → RDS payments-db (Multi-AZ)
├─ /api/catalog/* → ECS "catalog" → DynamoDB products
└─ /api/sessions/* → ECS "sessions" → ElastiCache sessions-cache
(공통)
↓ AWS Backup
├─ 매일 백업
└─ 다른 리전 복사
각 서비스가 자기 DB를 갖는 게 핵심이다.
2. 서비스마다 어떤 DB를 골랐나
| 서비스 | DB | 이유 |
|---|---|---|
| orders | RDS PostgreSQL | 트랜잭션 · 조인 · 정형 데이터 |
| users | RDS PostgreSQL | 트랜잭션 · 인증 일관성 |
| payments | RDS PostgreSQL + Multi-AZ | 강한 일관성 · 감사 로그 |
| catalog | DynamoDB | 단순 조회 · 무한 확장 |
| sessions | ElastiCache Redis | 초저지연 · TTL |
61장의 의사결정 트리가 그대로 적용됐다.
3. 가용성 설계의 층
서비스 단위:
ECS Service desiredCount ≥ 2
ALB Multi-AZ
Auto Scaling
DB 단위:
RDS Multi-AZ
Aurora cluster (필요 시)
DynamoDB는 기본 멀티 AZ
백업 단위:
AWS Backup daily
Cross-Region 복사 (선택)
Vault Lock (선택)
세 층이 합쳐져야 진짜 가용성이 만들어진다.
4. 읽기 부하가 늘어날 때
Phase 1: Primary 한 대로 시작
Phase 2: 트래픽 늘면 Read Replica 추가
Phase 3: 더 늘면 Aurora 전환 (빠른 Replica)
Phase 4: 글로벌이면 Aurora Global Database
캐시 계층은 Phase 1부터 끼우는 게 흔하다.
“DB가 느려서 못 살겠다” 보다는 “캐시를 일단 끼우자” 가 먼저
5. 쓰기 부하가 늘어날 때
Phase 1: 인스턴스 사양 업
Phase 2: 핫 데이터를 DynamoDB로 분리
Phase 3: 이벤트 기반 분리 (다음 단원 73~77장)
Phase 4: 샤딩 (수동 분할)
관계형 DB의 쓰기 확장은 수평 확장이 어렵다.
일정 규모를 넘으면 데이터 모델을 재검토한다.
6. 서비스 간 데이터 공유
orders 가 users 정보가 필요할 때 — 70장에서 본 세 패턴 중 하나.
1. 동기 API (단순)
2. 이벤트 + 로컬 복제 (느슨한 결합)
3. CQRS / BFF (대규모)
이벤트 기반은 다음 단원(메시징)에서 본격적으로 다룬다.
7. 운영 점검 체크리스트
각 DB마다 다음을 확인한다.
□ Multi-AZ / Cluster 켜졌는가
□ 자동 백업 (PITR) 켜졌는가
□ 보관 기간이 충분한가 (최소 7일, 권장 30일)
□ deletion_protection 켜졌는가
□ publicly_accessible = false 인가
□ 보안 그룹이 ECS Task SG 만 허용하는가
□ 비밀번호가 Secrets Manager에 있는가
□ ReplicaLag · CPU · Connections 알람이 있는가
□ AWS Backup Plan에 포함됐는가
□ 복구를 한 번이라도 시뮬레이션했는가
8. 우리 서비스의 DB Terraform 묶음 (요약)
# orders 서비스 모듈
module "orders_db" {
source = "./modules/rds-postgres"
identifier = "orders"
instance_class = "db.t4g.small"
multi_az = true
backup_retention_period = 7
deletion_protection = true
subnet_group_name = aws_db_subnet_group.private.name
allowed_sg_id = aws_security_group.orders_task.id
}
# 같은 모듈을 users · payments 에도 적용
module "users_db" { source = "./modules/rds-postgres" ... }
module "payments_db" { source = "./modules/rds-postgres" ... }
# DynamoDB
resource "aws_dynamodb_table" "products" {
name = "products"
billing_mode = "PAY_PER_REQUEST"
hash_key = "product_id"
attribute {
name = "product_id"
type = "S"
}
point_in_time_recovery {
enabled = true
}
}
# ElastiCache
resource "aws_elasticache_replication_group" "sessions" {
replication_group_id = "sessions-cache"
...
}
# AWS Backup
resource "aws_backup_plan" "daily" {
...
resources = [
module.orders_db.arn,
module.users_db.arn,
module.payments_db.arn,
aws_dynamodb_table.products.arn,
]
}
같은 모듈을 인스턴스화 — 새 서비스를 추가할 때 한 묶음으로 복제.
9. 이렇게 쓰면 망한다 — 통합 단계의 흔한 함정
함정 1. DB 보안 그룹이 ECS Task SG에서 안 열려 있다
연결이 끝없이 timeout. “DB는 살아 있는데 안 보임” 증상.
함정 2. 비밀번호를 평문 환경 변수로 박는다
배포 자동화 단계에서 비밀번호가 로그에 남는다.
항상 Secrets Manager → ECS Task Definition의
secrets로 주입
함정 3. 캐시가 죽으면 서비스가 같이 죽는다
캐시 실패 시 DB로 우회하는 경로를 안 만들어 둠.
함정 4. 모니터링 알람이 없다
DB 부하가 100% 인데 며칠 후에야 안다.
CPU · Connections · ReplicaLag · Throttle 은 거의 항상 켠다
10. 한 줄로 정리
데이터 계층은 “어떤 DB를 어디에 쓸지” + “어떻게 보호할지” 의 두 결정으로 완성되며,
서비스별 분리와 백업 · 복구 시뮬레이션이 운영의 진짜 안전망이다
11. 이 장의 핵심 정리
- Part 11 부품들이 모이면 MSA 데이터 계층이 완성된다.
- 서비스마다 자기 DB를 가진다 — RDS · DynamoDB · ElastiCache 를 워크로드별로.
- Multi-AZ · Replica · Cluster 는 가용성, AWS Backup · PITR · Vault Lock은 회복성을 담당한다.
- 캐시는 거의 항상 끼우는 게 운영 비용을 가장 빠르게 낮춘다.
- 다음 단원은 서비스 간 통신을 다룬다 — 데이터를 어떻게 흘릴지.