2.3. 데이터베이스의 한계와 개선 - 100-hours-a-week/KTB4-13th-wiki GitHub Wiki
V2 서비스 DB 인프라 도입 판단
1. 결론
V2 DB는 RDS for MySQL Multi-AZ DB Instance로 구성한다.
- App과 DB를 분리한다.
- RDS Single-AZ가 아니라 Multi-AZ DB Instance를 사용한다.
- EC2에서 MySQL을 직접 이중화하지 않는다.
- 초기에는 Read Replica를 추가하지 않는다.
결론의 근거는 다음과 같다.
- V2 목표 매출은 월 1억 5천만 원이다.
- AWS SLA의 가용성 수치를 비용 판단용 중단시간 예산으로 사용하면 Single-AZ와 Multi-AZ의 중단시간 차이는 월 194.4분이다.
- 이 차이로 줄어드는 직접 매출 손실은 목표 매출 기준 월 약 67만 5천 원이다.
- RDS Multi-AZ의 추가비용은 월 약 11만 9,600원이다.
- 손실 회피액이 추가비용보다 약 55만 5,400원 크므로 Multi-AZ를 선택한다.
- 신입 주니어 개발자 2명의 구축과 반복 운영 작업시간을 비용으로 바꾸면, EC2 직접 운영은 첫해 월평균 약 149만 5,700원이고 RDS Multi-AZ는 약 58만 300원이다.
이 계산에는 데이터 유실, 복구, 정산, 환불, 고객 문의와 사용자 이탈 손실을 넣지 않았다. 직접 매출 손실만으로 결론이 나오므로 이러한 간접손실을 임의로 부풀리지 않았다.
2. 의사결정 가정
실제 운영 이력이 없는 V2에서 결론을 내리기 위해 다음 값을 고정한다.
| 항목 | 적용값 | 사용 이유 |
|---|---|---|
| 목표 MAU | 1,000,000명 | V2 사업 목표 |
| 평균 DAU | 100,000명 | MAU × 월평균 이용일 3일 ÷ 30일 |
| 월 목표 매출 | 150,000,000원 | 제휴수수료 매출 기준 |
| 한 달 | 30일, 43,200분 | 비용과 손실 계산 기간 통일 |
| RDS Single-AZ 가용성 | 99.5% | AWS SLA 수치를 비용 판단용 중단시간 예산으로 사용 |
| RDS Multi-AZ 가용성 | 99.95% | AWS SLA 수치를 비용 판단용 중단시간 예산으로 사용 |
| RDS Single-AZ 비용 | 약 120,700원/월 | db.t4g.medium, gp3 100GB 기준 |
| RDS Multi-AZ 비용 | 약 240,300원/월 | db.t4g.medium, gp3 100GB 기준 |
| 작업 인력 | 신입 주니어 개발자 2명 | AWS·MySQL 기본 사용 경험은 있으나 운영용 DB 이중화 경험은 없음 |
| 개발자 비용 | 1명당 시간당 30,000원 | 1명당 연간 회사 부담 비용 6,000만 원, 연 2,000시간 기준 |
| EC2 최초 구축시간 | 2명 작업시간 합계 288시간 | 1명당 144시간, 약 18근무일 |
| EC2 반복 운영시간 | 2명 작업시간 합계 월 22시간 | Patch·복제·Backup·장애훈련·예외 대응 포함 |
| RDS 최초 구축시간 | 2명 작업시간 합계 40시간 | Network·RDS 설정·Failover·복원시험 포함 |
| RDS 반복 운영시간 | 2명 작업시간 합계 월 8시간 | 유지보수 검토·Alarm·Backup·정기시험·예외 대응 포함 |
| 환율 | 1달러당 1,378.04원 | 가격 비교 기준 |
| 부가가치세 | 제외 | AWS 표시가격 비교 기준 |
AWS SLA는 실제 장애시간의 예측값이 아니라 서비스 크레딧 기준이다. 이 문서에서는 내부 장애 이력이 없는 상황에서 두 구성의 위험비용을 같은 기준으로 비교하기 위한 의사결정 가정으로만 사용한다.
DB 사양도 확정값이 아니다. t4g.medium·100GB는 구조별 비용을 비교하기 위한 동일 조건이며 실제 사양은 부하 시험으로 결정한다.
3. 판단 순서
App과 DB를 분리해야 하는가?
↓ 예
Single-AZ의 손실이 Multi-AZ 비용보다 큰가?
↓ 예
Primary–Standby를 EC2와 RDS 중 어디에 구현할 것인가?
↓ RDS
읽기 병목 때문에 Read Replica가 필요한가?
↓ 근거 없음
RDS for MySQL Multi-AZ DB Instance만 도입
각 단계에서 비용 대비 효과가 확인되지 않으면 다음 단계로 넘어가지 않는다.
4. 1단계: App과 DB 분리
V2는 여러 App Instance가 회원·도서·주문·결제 데이터를 함께 사용한다. App Instance 안에 MySQL을 두면 다음 문제가 발생한다.
- App 교체와 Auto Scaling이 DB의 생명주기와 묶인다.
- 여러 App이 하나의 데이터 원본을 안정적으로 공유하기 어렵다.
- App과 DB의 CPU, Memory와 Storage를 따로 확장할 수 없다.
- App Instance 장애가 API와 DB 장애를 동시에 일으킨다.
- Backup과 복구 절차가 App 운영에 종속된다.
따라서 App과 DB를 분리한다.
5. 2단계: Single-AZ와 Multi-AZ 비교
5.1 추가비용
| 구성 | 월 비용 |
|---|---|
| RDS Single-AZ | 약 120,700원 |
| RDS Multi-AZ DB Instance | 약 240,300원 |
| Multi-AZ 추가비용 | 약 119,600원 |
5.2 중단시간 예산
한 달
= 30일 × 24시간 × 60분
= 43,200분
Single-AZ 중단시간 예산
= 43,200분 × (1 - 99.5%)
= 216분/월
Multi-AZ 중단시간 예산
= 43,200분 × (1 - 99.95%)
= 21.6분/월
Multi-AZ가 줄이는 중단시간
= 216분 - 21.6분
= 194.4분/월
5.3 직접 매출 손실
분당 평균 매출
= 150,000,000원 ÷ 43,200분
= 약 3,472원
Single-AZ 직접 매출 손실
= 216분 × 약 3,472원
= 약 750,000원/월
Multi-AZ 직접 매출 손실
= 21.6분 × 약 3,472원
= 약 75,000원/월
Multi-AZ의 직접 매출 손실 회피액
= 750,000원 - 75,000원
= 약 675,000원/월
5.4 손익 비교
Multi-AZ 월 순효과
= 직접 매출 손실 회피액 - Multi-AZ 추가비용
= 675,000원 - 119,600원
= 약 555,400원
목표 매출 달성률별 결과는 다음과 같다.
| 목표 매출 달성률 | 월 매출 | 손실 회피액 | Multi-AZ 추가비용 | 월 순효과 | 판단 |
|---|---|---|---|---|---|
| 10% | 15,000,000원 | 67,500원 | 119,600원 | -52,100원 | Single-AZ가 저렴함 |
| 17.7% | 약 26,600,000원 | 약 119,600원 | 119,600원 | 약 0원 | 손익분기점 |
| 25% | 37,500,000원 | 168,750원 | 119,600원 | 49,150원 | Multi-AZ가 유리함 |
| 50% | 75,000,000원 | 337,500원 | 119,600원 | 217,900원 | Multi-AZ가 유리함 |
| 100% | 150,000,000원 | 675,000원 | 119,600원 | 555,400원 | Multi-AZ가 유리함 |
Multi-AZ의 직접 매출 손익분기점은 월 매출 약 2,660만 원이다.
손익분기 월 매출
= 119,600원 ÷ (99.95% - 99.5%)
= 약 26,600,000원
V2 목표 매출 1억 5천만 원은 손익분기 매출의 약 5.6배다. 목표 매출의 25%만 달성해도 직접 매출 손실 회피액이 추가비용보다 크다.
따라서 RDS Multi-AZ DB Instance를 채택한다.
5.5 RPO 0 목표의 처리
RDS Multi-AZ DB Instance는 다른 AZ의 Standby에 동기식으로 데이터를 복제한다. 이 구성은 Instance 또는 AZ 장애에서 커밋 데이터가 유실될 위험을 줄인다.
다만 Multi-AZ는 다음 문제를 막지 못한다.
- 잘못된 SQL 실행
- Application 오류에 의한 데이터 변경
- 사용자나 관리자의 논리 삭제
- 계정 탈취 후 정상 권한으로 수행된 변경
따라서 Multi-AZ와 별도로 자동 Backup, 특정 시점 복원과 정기 복원시험을 유지한다. 데이터 유실 방지 효과는 이번 손익 계산에 넣지 않았으므로 Multi-AZ 결론을 과대평가하지 않는다.
6. 3단계: EC2 직접 운영과 RDS Multi-AZ 비교
두 방식 모두 Primary–Standby를 제공한다는 전제에서 비교한다.
작업 인력은 AWS와 MySQL의 기본 사용 경험은 있지만 운영용 DB 이중화 경험은 없는 신입 주니어 개발자 2명이다. 기존 Terraform Module, Failover 자동화와 운영절차는 없다고 가정한다. 외부 DBA 또는 SRE의 검토비용은 두 방식 모두에서 제외한다.
6.1 표시가격만 비교했을 때
| 구성 | 월 인프라 비용 |
|---|---|
| EC2 MySQL Primary–Standby 하한 | 약 115,700원 |
| RDS for MySQL Multi-AZ DB Instance | 약 240,300원 |
| RDS 표시가격 차이 | 약 124,600원 |
EC2 비용에는 DB Node 2대, EBS와 Snapshot만 들어 있다. Witness, Fencing, Proxy, 교차 AZ 통신, Monitoring과 Log 보관비는 빠져 있다.
6.2 작업시간 산정 기준
작업시간은 개발자 2명의 시간을 합산한다. 두 사람이 각각 8시간씩 작업하면 작업시간 합계는 16시간이다.
신입 개발자는 고가용성 구조, Fencing, Split-brain 방지, 장애 복구와 데이터 정합성을 학습하고 반복 검증해야 한다. 기존에 사용한 52시간은 경험 있는 담당자가 검증된 자동화를 재사용할 때 가능한 수준이며 현재 인력 조건에는 적절하지 않다.
개발자 1명의 시간당 비용은 3만 원으로 가정한다.
개발자 1명의 연간 회사 부담 비용 60,000,000원
÷ 연간 근무시간 2,000시간
= 시간당 30,000원
6.3 EC2 최초 구축 작업시간
| EC2 구축 작업 | 2명 작업시간 합계 | 1명당 기간 |
|---|---|---|
| MySQL 고가용성 학습과 구조 설계 | 48시간 | 3일 |
| EC2·Network·보안·자동 배포 구성 | 32시간 | 2일 |
| MySQL 설치·보안 설정과 복제 구성 | 48시간 | 3일 |
| 장애 감지·승격·Fencing·Writer Routing 구현 | 64시간 | 4일 |
| Backup·Binlog·PITR·Monitoring 구성 | 32시간 | 2일 |
| 장애·복원·Patch Rollback 시험과 운영절차 작성 | 64시간 | 4일 |
| 합계 | 288시간 | 1명당 18근무일 |
두 명이 모든 작업을 완전히 병렬로 처리할 수 없으므로 실제 완료기간은 약 4주로 본다.
EC2 최초 구축 인건비
= 288시간 × 30,000원
= 8,640,000원
12개월 월 환산액
= 8,640,000원 ÷ 12개월
= 720,000원/월
6.4 RDS 최초 구축 작업시간
RDS도 설정과 시험이 필요하므로 작업시간을 0으로 두지 않는다.
| RDS 구축 작업 | 2명 작업시간 합계 |
|---|---|
| DB Subnet Group·Security Group·KMS 설정 | 12시간 |
| RDS·Backup·Parameter·Alarm 설정 | 12시간 |
| Application 연결·Failover·복원시험과 운영절차 작성 | 16시간 |
| 합계 | 40시간 |
RDS 최초 구축 인건비
= 40시간 × 30,000원
= 1,200,000원
12개월 월 환산액
= 1,200,000원 ÷ 12개월
= 100,000원/월
6.5 반복 운영 작업시간
Query·Index·Schema 최적화와 용량 계획처럼 두 방식에 공통인 Application 업무는 제외한다. DB 인프라를 유지하기 위한 작업만 비교한다.
| 반복 작업 | EC2 직접 운영 | RDS Multi-AZ |
|---|---|---|
| OS·MySQL Patch와 Rollback 확인 | 6시간 | AWS 관리, 개발자 작업 제외 |
| 복제·Witness·Fencing·Proxy 점검 | 4시간 | AWS 관리, 개발자 작업 제외 |
| Backup·Binlog·Alarm 점검 | 4시간 | 2시간 |
| 분기별 Failover·복원시험의 월 환산 | 4시간 | 4시간 |
| 예외 대응 예비시간 | 4시간 | 2시간 |
| 합계 | 22시간/월 | 8시간/월 |
RDS에서도 Backup 상태 확인, Maintenance Window 검토, Failover와 복원시험, 장애 알림 확인은 팀이 수행한다. 따라서 RDS 운영시간을 0으로 계산하지 않는다.
EC2 반복 운영 인건비
= 22시간 × 30,000원
= 660,000원/월
RDS 반복 운영 인건비
= 8시간 × 30,000원
= 240,000원/월
6.6 첫해 월평균 총비용
| 항목 | EC2 직접 운영 | RDS Multi-AZ |
|---|---|---|
| 기본 인프라 | 115,700원 | 240,300원 |
| 최초 구축비 12개월 환산 | 720,000원 | 100,000원 |
| 반복 운영 인건비 | 660,000원 | 240,000원 |
| 첫해 월평균 총비용 | 1,495,700원 | 580,300원 |
EC2 직접 운영은 첫해 월평균 약 91만 5,400원 더 비싸다.
최초 구축비를 모두 반영한 이후의 월 비용도 다음과 같다.
| 안정화 이후 | EC2 직접 운영 | RDS Multi-AZ |
|---|---|---|
| 인프라와 반복 운영비 | 775,700원 | 480,300원 |
| RDS 대비 차이 | +295,400원 | 기준 |
EC2 비용에는 Witness, Proxy, 교차 AZ 통신, 추가 Monitoring과 Log 비용이 아직 포함되지 않았다. MySQL 공식 InnoDB Cluster를 사용하면 최소 3개의 MySQL Server가 필요하므로 실제 차이는 더 커진다.
6.7 판단
신입 주니어 개발자 2명에게 EC2 MySQL 고가용성 구성을 직접 운영하게 하면 다음 문제가 발생한다.
- RDS보다 월 비용이 높다.
- 약 4주의 초기 구축기간이 필요하다.
- 서비스 기능 개발에 사용할 시간이 줄어든다.
- 장애 전환과 데이터 정합성 오류를 경험 부족으로 놓칠 위험이 있다.
- 야간 장애 대응을 두 명이 지속적으로 담당해야 한다.
따라서 Primary–Standby는 EC2에서 직접 운영하지 않고 RDS Multi-AZ DB Instance로 구현한다.
7. 4단계: Read Replica 도입 여부
Multi-AZ의 Standby는 장애 전환용이며 읽기 Query를 처리하지 않는다. 그러나 예상 조회 비중 83%와 추정 QPS만으로 Read Replica를 추가하지 않는다.
RDS Read Replica 1대의 비교용 비용은 월 약 120,700원이다. 다음 조건을 모두 충족할 때만 추가한다.
- 실제 데이터로 부하 시험을 수행한다.
- Query Plan, Index, Paging, N+1과 Connection Pool을 먼저 개선한다.
- Writer Class와 Storage를 조정한 뒤에도 응답시간 목표를 위반한다.
- 지연을 허용하는 읽기 Query가 병목의 주원인임을 측정한다.
- 병목으로 인한 월 손실이 Read Replica 비용과 Application 변경비보다 크다.
현재는 이를 입증할 측정자료가 없으므로 초기 V2에는 Read Replica를 추가하지 않는다.
8. 최종 구성
사용자
↓
ALB
├─ App A
└─ App B
↓
RDS for MySQL Multi-AZ DB Instance
├─ Primary Writer
├─ 다른 AZ의 동기식 Standby
├─ 관리형 자동 Failover
├─ 자동 Backup·PITR
└─ Monitoring·Alarm
적용 사항은 다음과 같다.
- DB는 서로 다른 AZ의 Private Subnet에 배치한다.
- DB Port는 App Security Group에서만 허용한다.
- KMS Storage 암호화와 TLS를 적용한다.
- 주문·결제 변경 API에 Idempotency Key를 적용한다.
- 자동 Backup과 특정 시점 복원을 설정한다.
- Application의 DNS Cache, Connection 재연결과 제한된 재시도를 검증한다.
- Failover 시험으로 5분 이내 복구와 커밋 데이터 유실 여부를 확인한다.
- 실제 읽기 병목이 확인되기 전에는 Read Replica를 추가하지 않는다.
9. 운영 전 검증
9.1 용량 시험
- 3년 차 예상 데이터 규모를 생성한다.
- 정상 약 625 RPS와 검증 약 1,250 RPS를 시험한다.
- DB 약 2,500 QPS와 5,000 QPS 구간을 시험한다.
- CPU, Memory, IOPS, Connection과 Query P95·P99를 측정한다.
- 시험을 통과하는 최소 DB Class와 Storage를 결정한다.
9.2 장애와 복구 시험
- 강제 Failover 시 DB 복구시간과 사용자 체감 중단시간을 구분한다.
- DNS Cache와 Connection Pool의 재연결을 확인한다.
- 긴 Transaction과 높은 부하 중 Failover를 시험한다.
- 자동 Backup과 특정 시점 복원을 시험한다.
- 커밋 완료 데이터의 손실 여부를 확인한다.
9.3 운영 후 재검토
다음 값은 운영 3개월 뒤 실제 자료로 다시 계산한다.
- 실제 월 매출
- 실제 장애 횟수와 중단시간
- 복구·정산·환불·고객 문의 비용
- EC2와 RDS의 실제 청구금액
- DB 운영에 사용한 작업시간
월 매출이 손익분기점인 약 2,660만 원보다 장기간 낮거나 실제 Single-AZ 위험이 가정보다 현저히 낮다는 근거가 생기면 Multi-AZ 경제성을 다시 검토한다.
10. 최종 결정 기록
| 결정 항목 | 결론 | 핵심 근거 |
|---|---|---|
| App과 DB 분리 | 적용 | 여러 App의 중앙 데이터 저장소가 필요함 |
| DB 가용성 | Multi-AZ | 목표 매출 기준 손실 회피액 675,000원이 추가비용 119,600원보다 큼 |
| 구현 방식 | RDS for MySQL | 신입 주니어 개발자 2명 기준 EC2 직접 운영의 첫해 월평균 비용이 약 915,400원 더 큼 |
| DB 사양 | 부하 시험 후 확정 | db.t4g.medium·100GB는 가격 비교용 사양임 |
| Read Replica | 초기 제외 | 읽기 병목과 비용 회수 효과가 확인되지 않음 |
따라서 V2의 초기 DB 구성은 RDS for MySQL Multi-AZ DB Instance로 확정한다.
참고 자료
아래 자료는 2026년 9월 18일 기준으로 확인했다.
- 매출 가정: 알라딘 Thanks to Blogger, Bookshop.org Affiliates, Libro.fm Affiliates, Shopify 전환율 자료
- 관리 책임: AWS RDS와 EC2의 관리 책임 비교
- EC2 MySQL 고가용성 구성: MySQL InnoDB Cluster 개요, Production InnoDB Cluster 배포, MySQL Router와 InnoDB Cluster
- EC2 요금: AWS EC2 On-Demand 요금, 서울 리전 Amazon EC2 Price List
- RDS 요금: AWS RDS for MySQL 요금, 서울 리전 Amazon RDS Price List
- 가용성: AWS RDS SLA, RDS Multi-AZ DB Instance, RDS Multi-AZ Failover
- 장애 벤치마크: Uptime Institute Annual Outage Analysis 2025
- Backup과 읽기 확장: AWS RDS Backup과 PITR, AWS RDS Read Replica