RPO와 RTO로 복구 목표 정하기
RPO와 RTO로 복구 목표 정하기
RPO는 어느 시점까지의 데이터를 반드시 되찾아야 하는지, RTO는 중단 후 언제까지 서비스를 다시 사용할 수 있어야 하는지를 정한다. 두 값을 기술팀이 임의로 낮게 정하면 비용과 복잡성이 커지고, 느슨하게 정하면 사고 때 비즈니스가 감당하지 못하는 손실이 생긴다. 업무 영향에서 목표를 도출하고 각 의존성의 실제 복구 시간으로 검증해야 한다.
목차
- #복구 목표가 없으면 좋은 설계를 고를 수 없다
- #RPO는 허용 가능한 데이터 손실의 시간 경계다
- #RTO는 허용 가능한 서비스 중단 시간이다
- #목표와 실제 결과를 구분한다
- #모든 데이터와 기능에 같은 목표를 적용하지 않는다
- #비즈니스 영향에서 RPO와 RTO를 도출한다
- #의존성 그래프로 전체 목표를 검증한다
- #복구 전략별 비용과 복잡성
- #Partial Recovery와 Degraded Mode를 설계한다
- #RPO 계산에서 놓치기 쉬운 데이터
- #RTO를 단계별 시간 예산으로 나눈다
- #재구성한 복구 목표 문서와 검증 코드
- #복구 훈련으로 목표를 증명한다
- #목표를 검토하고 변경하는 시점
- #마무리
- #참고 자료
- #관련 노트
복구 목표가 없으면 좋은 설계를 고를 수 없다
“장애가 나도 최대한 빨리 복구하자”는 말은 방향일 뿐 설계 기준이 아니다. backup 주기, replica 지역, warm standby 용량, 자동 failover, 운영 인력과 비용을 결정하려면 수치가 필요하다.
선택 A: 하루 한 번 backup, 수동 복구
선택 B: 5분 주기 log archive, 자동화된 restore
선택 C: 다른 region에 warm standby
선택 D: multi-region active/active
일반적으로 아래로 갈수록 복구 지점과 시간은 짧아질 수 있지만 비용, 데이터 일관성, 운영 복잡성도 커진다.
flowchart LR
A[업무 영향 분석] --> B[RPO·RTO 목표]
B --> C[복구 전략 선택]
C --> D[구현과 Runbook]
D --> E[Restore Drill]
E --> F{목표 달성?}
F -- 아니오 --> C
F -- 예 --> G[정기 재검토]목표가 없다면 active/active가 과도한지, 하루 backup이 부족한지 판단할 수 없다. 기술적으로 가장 빠른 복구가 항상 비즈니스에 가장 좋은 설계도 아니다.
장애의 종류와 영향 범위를 정하지 않은 채 RPO 5분, RTO 30분 같은 숫자만 적지 않는다. database 삭제, region 장애, 계정 침해는 필요한 복구 경로가 다르다.
RPO는 허용 가능한 데이터 손실의 시간 경계다
RPO는 Recovery Point Objective다. 사고가 발생했을 때 어느 과거 시점까지의 데이터를 복구해야 하는지 나타낸다.
incident time: 14:30
RPO: 15 minutes
required recovery point:
14:15 이후
14:18 상태로 복구하면 목표를 만족하지만 14:00 full backup으로만 복구하면 30분의 데이터를 잃어 목표를 만족하지 못한다.
timeline
title RPO 15분 예시
14:00 : Full backup
14:15 : 허용 가능한 가장 오래된 복구 지점
14:22 : 실제 복구 가능 지점
14:30 : 사고 발생RPO 0은 데이터 손실을 허용하지 않는다는 뜻에 가깝다. 이를 달성하려면 동기 복제나 업무 수준의 중복 기록을 검토해야 하지만, 논리 오류와 계정 침해까지 자동으로 해결되지는 않는다.
RPO를 backup 주기와 완전히 같은 값으로 보면 안 된다.
backup interval: 15 minutes
backup duration: 12 minutes
upload delay: 5 minutes
occasional failed run: possible
observed recovery gap may exceed 15 minutes
15분마다 backup을 시작해도 완료와 원격 보존까지 시간이 걸리고 실패한 실행이 있을 수 있다. 실제로 복구 가능한 최신 지점의 나이를 측정해야 한다.
recovery point age
= current time
- newest verified recoverable point
RTO는 허용 가능한 서비스 중단 시간이다
RTO는 Recovery Time Objective다. 중단 시점부터 업무 기능을 다시 사용할 수 있을 때까지 허용되는 최대 시간이다.
service interruption: 14:30
RTO: 2 hours
service must be restored by:
16:30
RTO에는 데이터 restore 시간만 들어가지 않는다.
detection
+ incident declaration
+ decision and approval
+ access acquisition
+ infrastructure provisioning
+ data restoration
+ application startup
+ integrity validation
+ traffic cutover
= total recovery time
데이터베이스가 40분 만에 기동됐어도 의사결정 30분, 권한 대기 20분, smoke test 40분, DNS 전환 20분이 걸리면 총 2시간 30분이다.
detect: 10m
decide: 20m
access: 15m
provision: 25m
restore: 40m
validate: 25m
cutover: 15m
----------------
total: 150m
RTO 120분을 30분 초과한다. 데이터베이스 restore만 최적화하기보다 어느 단계가 시간 예산을 넘겼는지 봐야 한다.
RTO는 특정 재해 사건에서 복구해야 하는 시간 목표다. 월간 availability SLO는 전체 관측 기간의 성공 비율을 다룬다. 서로 영향을 주지만 같은 숫자는 아니다.
목표와 실제 결과를 구분한다
RPO와 RTO는 목표다. 설계 문서에 적었다고 달성되는 값이 아니다. 실제 결과를 별도로 기록한다.
Target RPO = 15 minutes
Observed recovery gap = 37 minutes
Target RTO = 2 hours
Observed recovery time = 2 hours 42 minutes
표기법은 조직마다 다를 수 있으므로 문서에서는 다음처럼 풀어 쓰는 편이 명확하다.
| 항목 | 의미 |
|---|---|
| Target RPO | 비즈니스가 허용한 최대 데이터 손실 시간 |
| Observed recovery gap | drill에서 사고 시점과 실제 복구 지점의 차이 |
| Target RTO | 비즈니스가 허용한 최대 중단 시간 |
| Observed recovery time | drill에서 탐지부터 기능 복구까지 걸린 시간 |
다음 상황도 구분한다.
Backup 시스템 표시:
- latest point 14:28
실제 restore drill:
- log gap 때문에 14:11까지만 복구
Dashboard RPO estimate: 2m
Observed recovery gap: 19m
백업 metadata는 예상치이고 restore drill은 검증된 결과다. 두 값이 다르면 더 보수적인 실제 결과로 위험을 평가한다.
모든 데이터와 기능에 같은 목표를 적용하지 않는다
서비스 전체에 RPO 0, RTO 5분을 요구하면 비용이 급격히 늘어난다. 반대로 전체에 RPO 24시간을 적용하면 핵심 거래 데이터를 잃을 수 있다.
업무 기능과 데이터 등급을 나눈다.
| 기능·데이터 | 예시 Target RPO | 예시 Target RTO | 이유 |
|---|---|---|---|
| 결제 원장 | 0에 가까움 | 30분 | 금전 정합성 |
| 게시글 원본 | 15분 | 2시간 | 사용자 생성 데이터 |
| 사용자 업로드 | 1시간 | 4시간 | 재업로드 비용 |
| 검색 index | 24시간 또는 재생성 | 8시간 | 원본 DB에서 재구축 |
| 추천 결과 cache | 없음 | 1시간 | 없어도 기능 축소 가능 |
| 분석 집계 | 24시간 | 48시간 | 사용자 경로와 분리 |
숫자는 예시다. 중요한 점은 같은 애플리케이션 안에서도 가치와 재생성 가능성이 다르다는 것이다.
서비스 tier를 만들 수 있다.
Tier 0
- 인증, key management, 핵심 거래
- 가장 엄격한 목표와 정기적인 failover test
Tier 1
- 사용자 핵심 읽기·쓰기
- 짧은 RPO/RTO
Tier 2
- 검색, 알림, 추천
- degraded mode 허용
Tier 3
- 분석과 내부 도구
- 업무 시간 복구 가능
Tier 분류가 기술 인프라의 중요도만 반영해서는 안 된다. 내부 인증이 없으면 모든 사용자 서비스가 복구되지 않으므로 직접 매출이 없어도 Tier 0일 수 있다.
비즈니스 영향에서 RPO와 RTO를 도출한다
“다른 회사가 1시간이니 우리도 1시간”으로 정하지 않는다. 업무 중단과 데이터 손실 비용을 시간대별로 분석한다.
서비스 중단 15분
- 일시적인 요청 재시도
- 지원 문의 소수
서비스 중단 2시간
- 주문 누락
- 고객 지원 급증
- 파트너 SLA 영향
서비스 중단 8시간
- 정산 마감 실패
- 수동 처리 한계 초과
- 법적·계약상 보고 필요
데이터 손실도 별도로 본다.
5분 데이터 손실
- 자동 재전송 가능한 이벤트
1시간 데이터 손실
- 사용자 작성 내용 일부 유실
- 파트너 재처리 필요
24시간 데이터 손실
- 회계와 정산 재구성 불가능
비즈니스 담당자에게 “RPO가 몇 분이어야 하나요?”라고 묻기보다 구체적인 질문을 한다.
- 마지막 15분 주문을 잃으면 어떻게 복구할 수 있는가
- 고객이 요청을 다시 제출할 수 있는가
- 수동 reconciliation에 몇 명·몇 시간이 필요한가
- 2시간 중단 시 계약 위약과 지원 비용은 얼마인가
- 어떤 기능만 먼저 살아나면 손실을 크게 줄일 수 있는가
- 야간과 마감 시간의 영향이 다른가
이를 간단한 영향 곡선으로 정리할 수 있다.
| 중단 시간 | 추정 업무 영향 | 대응 가능성 |
|---|---|---|
| 0~15분 | 경미 | 자동 retry와 queue 흡수 |
| 15~60분 | 중간 | 운영팀 수동 처리 가능 |
| 1~4시간 | 높음 | 주문·지원 backlog 발생 |
| 4시간 이상 | 심각 | 계약·정산·고객 이탈 영향 |
RTO는 영향이 감당할 수 없는 수준으로 올라가기 전의 지점에서 정한다. 더 낮은 목표를 달성하는 비용과 비교해 최종 결정한다.
복구 중 수동 업무, on-call 피로, 개인정보 신고, 고객 신뢰와 같은 영향도 함께 평가한다.
의존성 그래프로 전체 목표를 검증한다
API의 RTO를 30분으로 정해도 database, key management, network가 2시간이면 달성할 수 없다.
flowchart TD
N[Network·DNS] --> A[Core API]
K[Key·Secrets] --> D[Database]
K --> A
D --> A
O[Object Storage] --> A
A --> W[Web]
D --> S[Search rebuild]
S --> W각 의존성의 목표와 실제 복구 시간을 표로 만든다.
| 구성 요소 | 필요 시점 | Target RTO | 최근 drill | 전체 경로 영향 |
|---|---|---|---|---|
| Network | 시작 즉시 | 20분 | 14분 | 모든 작업 선행 |
| KMS·Secret | DB 전 | 20분 | 31분 | DB·API 차단 |
| Database | API 전 | 60분 | 52분 | 핵심 기능 차단 |
| Core API | DB 후 | 30분 | 18분 | 사용자 기능 |
| Search | 나중 가능 | 8시간 | 5시간 | 축소 운영 가능 |
전체 RTO는 모든 숫자를 단순 합한 값이 아니다. 독립적인 작업은 병렬로 진행할 수 있고, 일부 기능은 나중에 복구할 수 있다.
network ─────── 14m
keys ───────────── 31m
infra ────────── 25m
database ───────────── 52m
application ───── 18m
validation ─── 12m
critical path:
keys → database → application → validation
Critical path를 기준으로 자동화와 사전 준비의 우선순위를 정한다. key 승인 31분이 병목이면 database restore throughput을 5분 줄이는 것보다 break-glass 절차를 개선하는 편이 효과적이다.
복구용 지역의 서비스 quota, DNS control plane, container registry, artifact repository도 의존성이다. primary 계정 장애 때 같은 계정의 IaC state와 secret만 참조하면 복구 경로가 끊긴다.
복구 전략별 비용과 복잡성
일반적으로 복구 목표가 짧을수록 더 많은 자원을 미리 준비한다.
| 전략 | 개념 | 일반적 특성 |
|---|---|---|
| Backup & Restore | 사고 후 인프라와 데이터 복구 | 낮은 상시 비용, 긴 RTO/RPO 가능 |
| Pilot Light | 핵심 데이터·최소 구성 상시 유지 | 중간 비용, scale-up 절차 필요 |
| Warm Standby | 축소된 전체 stack 상시 실행 | 더 짧은 RTO, 용량 확장 필요 |
| Active/Active | 여러 site가 평상시 traffic 처리 | 짧은 RTO/RPO 가능, 높은 복잡성 |
정확한 숫자는 workload와 공급자에 따라 달라지므로 전략 이름만 보고 보장하지 않는다.
flowchart LR
A[Backup & Restore
낮은 상시 비용·긴 복구] --> B[Pilot Light]
B --> C[Warm Standby]
C --> D[Active/Active
높은 상시 비용·짧은 복구 가능]이 순서는 절대적인 성능 보장이 아니라 일반적인 경향을 나타낸다. 핵심은 active/active가 자동으로 좋은 선택이 아니라는 점이다.
Active/active는 다음 문제를 추가한다.
- multi-writer conflict와 일관성
- region별 schema와 config drift
- 전역 traffic routing
- 장애 region 격리
- 논리 삭제와 손상의 동시 복제
- 정상 시에도 두 환경을 운영하는 비용
RPO가 짧아도 backup은 여전히 필요하다. 잘못된 데이터 변경은 모든 active site로 복제될 수 있기 때문이다.
Partial Recovery와 Degraded Mode를 설계한다
RTO를 “모든 기능 100% 복구”로만 정의하면 핵심 기능도 늦게 열릴 수 있다.
T+30m 로그인과 읽기 가능
T+60m 새 글 작성 가능
T+2h 이미지 업로드 가능
T+6h 검색 index 복구
T+12h 추천과 분석 복구
기능별 recovery milestone을 둔다.
| 시점 | 상태 | 사용자 기능 |
|---|---|---|
| 30분 | 최소 기능 | 로그인, 기존 글 조회 |
| 1시간 | 핵심 복구 | 글 작성·수정 |
| 2시간 | 주요 기능 | 이미지 업로드, 알림 |
| 8시간 | 완전 복구 | 검색, 추천, 분석 |
이를 통해 핵심 사용자 여정의 RTO와 전체 기능의 RTO를 구분할 수 있다.
Core RTO: 60 minutes
Full-service RTO: 8 hours
Degraded mode를 실제로 지원하려면 코드와 데이터 의존성을 분리해야 한다.
type ServiceCapabilities = {
articleRead: boolean;
articleWrite: boolean;
imageUpload: boolean;
search: boolean;
recommendation: boolean;
};
function recoveryCapabilities(
dependencies: {
database: boolean;
objectStorage: boolean;
searchIndex: boolean;
recommendationApi: boolean;
},
): ServiceCapabilities {
return {
articleRead: dependencies.database,
articleWrite: dependencies.database,
imageUpload: dependencies.database && dependencies.objectStorage,
search: dependencies.database && dependencies.searchIndex,
recommendation:
dependencies.database && dependencies.recommendationApi,
};
}
추천 API가 없다고 전체 페이지가 500이 되면 단계적 복구가 불가능하다. 선택적 기능은 timeout과 fallback을 두고 핵심 기능과 격리한다.
“DB RTO 1시간”보다 “사용자가 1시간 안에 자신의 글을 조회할 수 있다”가 더 검증 가능한 목표다.
RPO 계산에서 놓치기 쉬운 데이터
주 database의 최신 복구 시점만 확인하면 전체 업무 RPO를 과대평가할 수 있다.
order database: RPO 5m
payment provider reconciliation file: RPO 24h
object upload: RPO 1h
event queue: retention 30m
하나의 사용자 작업이 여러 저장소에 기록되면 가장 약한 지점과 재조정 능력을 봐야 한다.
sequenceDiagram
participant U as User
participant A as API
participant D as Database
participant O as Object Storage
participant Q as Event Queue
U->>A: 게시글 + 이미지 업로드
A->>O: 이미지 저장
A->>D: 게시글 row 저장
A->>Q: 검색 색인 이벤트DB는 14:25, object storage는 14:10, queue는 유실된 상태로 복구되면 게시글 row는 있지만 이미지가 없고 검색 index도 갱신되지 않는다.
데이터마다 다음을 기록한다.
- system of record인가 파생 데이터인가
- 생성 순서와 transaction 경계
- backup 또는 replication 방식
- 최신 검증된 복구 지점
- idempotent replay 가능 여부
- reconciliation source
- 삭제와 retention 정책
파생 데이터는 다시 만들 수 있더라도 원본 이벤트 retention이 충분해야 한다. queue가 30분 보존인데 index 재구축에 4시간이 필요하면 DB 전체 scan 같은 다른 경로가 있어야 한다.
시간 기반 RPO만으로 표현하기 어려운 데이터도 있다.
허용 데이터 손실:
- 결제 거래 0건
- 분석 이벤트 최대 10,000건
- 사용자 업로드 최대 15분
업무 단위의 허용 손실을 함께 기록하면 “RPO 15분”이 실제로 몇 건과 얼마의 금액인지 이해할 수 있다.
RTO를 단계별 시간 예산으로 나눈다
전체 RTO 120분을 선언한 뒤 각 단계가 알아서 빠르게 끝나길 기대해서는 안 된다.
Detection 5m
Declaration and decision 10m
Access and approval 10m
Infrastructure provisioning 20m
Data restore 45m
Application startup 10m
Validation 15m
Traffic cutover 5m
--------------------------------
Total 120m
Runbook에는 각 단계의 시작과 완료 조건을 둔다.
| 단계 | 시작 조건 | 완료 조건 |
|---|---|---|
| Detect | 사용자 SLI 이상 | 영향과 범위 확인 |
| Decide | disaster 후보 | IC가 전략 승인 |
| Provision | recovery site 결정 | network·compute 준비 |
| Restore | target point 선택 | DB가 목표 시점에서 기동 |
| Validate | app 연결 가능 | 정합성·smoke test 통과 |
| Cutover | 핵심 SLI 준비 | 제한 traffic 정상 |
자동화가 줄일 수 있는 시간과 사람 판단이 필요한 시간을 구분한다.
자동화 후보:
- recovery account IaC 배포
- backup 선택 후보 계산
- checksum과 log gap 검증
- application smoke test
- dashboard와 incident 문서 생성
사람 판단:
- 복구 target 승인
- data loss 허용 여부
- traffic cutover와 rollback
- 고객 커뮤니케이션
탐지 시간을 RTO 밖으로 빼면 안 된다. region이 이미 중단됐는데 40분 뒤 고객 문의로 발견하면 실제 사용자 중단은 그때부터 시작됐다.
복구 단계와 명령을 문서화하는 방법은 장애 대응 Runbook에 들어가야 할 내용에서 다뤘다.
재구성한 복구 목표 문서와 검증 코드
다음은 특정 회사 정책을 복사한 것이 아닌 workload별 목표 문서 예시다.
workload: article-platform
owner: content-platform
reviewed_at: 2026-04-01
scenarios:
- name: regional-outage
scope: primary-region
objectives:
core:
rpo_minutes: 15
rto_minutes: 60
full_service:
rpo_minutes: 60
rto_minutes: 480
- name: accidental-data-deletion
scope: relational-database
objectives:
core:
rpo_minutes: 5
rto_minutes: 120
dependencies:
- name: relational-database
recovery_order: 1
strategy: base-backup-and-log-replay
- name: object-storage
recovery_order: 1
strategy: versioned-cross-account-copy
- name: search-index
recovery_order: 2
strategy: rebuild-from-database
Drill 결과를 같은 목표와 비교한다.
type RecoveryObjective = {
rpoMinutes: number;
rtoMinutes: number;
};
type RecoveryObservation = {
recoveryGapMinutes: number;
recoveryTimeMinutes: number;
};
type ObjectiveResult = {
rpoMet: boolean;
rtoMet: boolean;
rpoMarginMinutes: number;
rtoMarginMinutes: number;
};
function evaluateRecovery(
objective: RecoveryObjective,
observed: RecoveryObservation,
): ObjectiveResult {
return {
rpoMet: observed.recoveryGapMinutes <= objective.rpoMinutes,
rtoMet: observed.recoveryTimeMinutes <= objective.rtoMinutes,
rpoMarginMinutes:
objective.rpoMinutes - observed.recoveryGapMinutes,
rtoMarginMinutes:
objective.rtoMinutes - observed.recoveryTimeMinutes,
};
}
테스트로 경계값을 고정한다.
import { describe, expect, it } from "vitest";
describe("evaluateRecovery", () => {
it("목표와 같은 값은 달성으로 본다", () => {
expect(
evaluateRecovery(
{ rpoMinutes: 15, rtoMinutes: 120 },
{ recoveryGapMinutes: 15, recoveryTimeMinutes: 120 },
),
).toEqual({
rpoMet: true,
rtoMet: true,
rpoMarginMinutes: 0,
rtoMarginMinutes: 0,
});
});
it("데이터 지점과 복구 시간을 독립적으로 평가한다", () => {
expect(
evaluateRecovery(
{ rpoMinutes: 15, rtoMinutes: 120 },
{ recoveryGapMinutes: 8, recoveryTimeMinutes: 142 },
),
).toMatchObject({
rpoMet: true,
rtoMet: false,
});
});
});
RPO는 만족했지만 RTO는 실패할 수 있고 그 반대도 가능하다. 둘을 하나의 drill_success boolean으로만 합치지 않는다.
결과 record 예시다.
{
"workload": "article-platform",
"scenario": "regional-outage",
"drill_id": "drill-example-2026-04",
"target_rpo_minutes": 15,
"observed_recovery_gap_minutes": 8,
"target_rto_minutes": 60,
"observed_recovery_time_minutes": 74,
"rpo_met": true,
"rto_met": false,
"critical_path": "key-access -> database-restore -> validation"
}
이 결과에서는 복구 지점은 목표를 만족하지만 핵심 기능이 14분 늦었다. 다음 개선은 backup 주기보다 critical path의 key 접근과 validation 자동화에 집중해야 한다.
복구 훈련으로 목표를 증명한다
복구 목표는 architecture diagram이 아니라 실제 drill로 증명한다.
검증 주기 예시
- Tier 0: 분기별 restore + 반기별 failover
- Tier 1: 반기별 full restore
- Tier 2: 연 1회 restore 또는 rebuild
- 중요 변경 직후: 관련 시나리오 재검증
주기는 예시이며 데이터 변화량, 규제, 변경 빈도, 사고 위험에 따라 정한다.
Drill에서 측정할 항목은 다음과 같다.
- 탐지부터 선언까지 시간
- recovery role 접근 시간
- 선택한 target과 실제 복구 지점
- backup download와 log replay 시간
- application start와 cache warm-up 시간
- 데이터 정합성 검증 시간
- 제한 traffic과 전체 traffic 전환 시간
- 수동 단계, 오류와 재시도
- 핵심 기능과 전체 기능 각각의 회복 시각
복구 훈련을 설계하고 격리하는 방법은 백업이 아니라 복구를 테스트해야 하는 이유에서 자세히 정리했다.
사고 전에 “RTO 60분 목표인데 실제 74분”이라는 사실을 발견했다면 drill은 가치가 있었다. 결과를 숨기지 않고 목표를 조정하거나 설계를 개선해야 한다.
목표가 비현실적일 수도 있다. 비즈니스가 5분 RTO를 원하지만 현재 설계와 예산으로 2시간이 걸린다면 세 선택지를 명시한다.
- 더 빠른 전략에 투자한다.
- degraded mode로 핵심 기능만 5분 안에 제공한다.
- 영향과 위험을 받아들이고 목표를 현실적으로 바꾼다.
문서에 낮은 숫자만 남기고 실제 차이를 방치하는 것이 가장 나쁘다.
목표를 검토하고 변경하는 시점
RPO와 RTO는 한 번 정하고 끝나는 숫자가 아니다.
재검토 trigger
- 사용자 수와 거래액의 큰 증가
- 새 규제와 계약
- database 크기와 restore 시간 증가
- architecture 또는 cloud account 변경
- 새 외부 dependency 추가
- backup·replication 방식 변경
- incident와 restore drill
- 조직과 on-call 구조 변경
분기 또는 반기마다 목표와 최근 실제 결과를 표로 본다.
| Workload | Target RPO | Observed gap | Target RTO | Observed time | 상태 |
|---|---|---|---|---|---|
| Core API | 15m | 8m | 60m | 74m | RTO 미달 |
| Search | 24h | 2h | 8h | 5h | 달성 |
| Analytics | 24h | 20h | 48h | 31h | 달성 |
목표보다 훨씬 좋은 결과가 지속되면 과투자 여부도 확인한다. Tier 3 분석 시스템에 active/active 비용을 쓰고 핵심 DB의 restore test가 실패하고 있다면 투자 우선순위가 잘못됐을 수 있다.
복구 전략 변경은 비용뿐 아니라 운영 복잡성도 포함한다.
total recovery investment
= infrastructure cost
+ engineering implementation
+ testing and training
+ on-call complexity
+ data consistency risk
마무리
RPO와 RTO는 재해 복구 문서에 들어가는 약어가 아니라, 데이터 손실과 서비스 중단을 어느 수준까지 감당할지 합의하는 기준이다.
RPO는 복구 지점의 시간 차이, RTO는 사용자 기능이 돌아올 때까지의 전체 시간이다. 목표값과 drill에서 관측한 실제값을 반드시 분리해야 한다.
실무 적용 순서는 다음과 같다.
- region 장애, 논리 삭제, 계정 침해처럼 시나리오를 정의한다.
- 업무 중단과 데이터 손실의 시간별 영향을 분석한다.
- workload와 데이터 tier별 Target RPO·RTO를 정한다.
- 핵심 기능과 전체 기능의 recovery milestone을 나눈다.
- 의존성 그래프와 critical path로 목표 달성 가능성을 검토한다.
- backup & restore, pilot light, warm standby, active/active의 비용과 복잡성을 비교한다.
- DB 밖의 object, queue, key, config와 artifact까지 RPO를 확인한다.
- 전체 RTO를 탐지·결정·복구·검증·전환 시간 예산으로 나눈다.
- 격리된 restore drill에서 실제 recovery gap과 recovery time을 측정한다.
- 성장, 변경, 사건과 drill 결과에 따라 목표와 투자를 갱신한다.
가장 낮은 RPO와 RTO가 항상 가장 좋은 목표는 아니다. 사용자와 비즈니스가 감당할 수 있는 손실을 명확히 하고, 그 목표를 반복해서 증명할 수 있는 설계가 좋은 재해 복구 전략이다.
참고 자료
- AWS Architecture Blog - Disaster Recovery Architecture, Part I
- AWS Architecture Blog - Backup and Restore with Rapid Recovery
- AWS Architecture Blog - Pilot Light and Warm Standby
- AWS Well-Architected Framework - Reliability Pillar