Block 4: DR & Failover Automation

전략 선택 → 장애 시나리오 → 자동화 파이프라인 → 훈련과 검증

DR 전략은 비용과 RTO의 교환

Backup & RestoreRPO 시간 단위, RTO 24시간 이내
복구 리전에 백업만 둡니다. 장애 시 IaC로 인프라를 만들고 데이터를 복원합니다.
Pilot LightRPO 분 단위, RTO 수십 분
데이터 복제와 DB는 상시 가동, 애플리케이션 서버는 필요할 때 배포합니다.
Warm StandbyRPO 초 단위, RTO 분 단위
축소된 전체 스택이 항상 실행됩니다. 장애 시 확장 후 트래픽을 받습니다.
Multi-site Active/ActiveRPO 거의 0, RTO 0에 근접
두 리전이 동시에 트래픽을 처리합니다. 비용과 데이터 일관성 설계 부담이 가장 큽니다.
비용, 복잡도 낮음RTO, RPO 짧음 →
이 쇼핑몰의 선택 order, payment, inventory는 Aurora Global Database, catalog, cart는 global cluster, Global Datastore. 모두 쓰기는 us-east-1 한 곳인 Warm Standby이고, 양 리전 쓰기(Active/Active)는 DSQL multi-Region을 택할 때의 선택지입니다.

서비스마다 RTO, RPO가 다르다

서비스데이터 스토어 (현재)us-east-1 장애 시RPO 성격전환 방식
order, payment, inventoryAurora PostgreSQL Global DBus-west-2 읽기 유지, 쓰기 중단계획 0, 비계획은 복제 lag만큼failover (allow-data-loss), global writer endpoint (앱 적용 필요)
catalogDocumentDB global clusterus-west-2 읽기 유지초 단위 (비동기)managed failover, 보통 1분 내 승격
cart, sessionElastiCache (Valkey) Global Datastoreus-west-2 읽기 유지복제 지연 보통 1초 미만수동 promote, 보통 1분 미만
이벤트MSK, Replicator 미구성us-west-2에 이벤트 없음미처리 이벤트가 us-east-1에 남음Replicator 구성 전에는 전환 불가
정적 자산S3 CRR + RTC복제본에서 읽기99.99% 객체 15분 이내 설계CloudFront origin group
컴퓨트리전별 EKS 클러스터us-west-2 확장statelessGitOps + 용량 확장
가장 약한 고리 이벤트 경로입니다. MSK Replicator가 없어 DB가 넘어가도 order.created 같은 미처리 이벤트는 us-east-1에 남습니다.

장애는 세 가지 크기로 온다

us-east-1 전체가 응답하지 않는 경우입니다.

계층자동사람이 결정
엣지 (CloudFront)GET/HEAD/OPTIONS는 origin group으로 자동 재시도쓰기 요청의 활성 리전 전환
catalog (DocumentDB)없음failover-global-cluster 실행
cart (ElastiCache)없음failover-global-replication-group 실행
order, payment (Aurora Global DB)없음failover-global-cluster 실행

결론: 읽기는 살아남지만 주문, 결제는 DB 승격과 쓰기 리전 전환이 끝날 때까지 멈춥니다. 순서를 정한 Runbook이 필요합니다.

리전은 정상이고 한 데이터 스토어만 문제인 경우입니다.

상황먼저 할 일
catalog 장애캐시된 상품 정보로 읽기 전용 모드
cart 장애세션 쿠키와 DB로 장바구니 재구성, 쓰기는 재시도 큐
데이터 손상 (잘못된 쓰기)복제본에도 전파되므로 PITR, 스냅샷으로 복구
리전 전환 판단"DB 하나 때문에 모든 서비스를 옮길 가치가 있는가"

원칙: 리전 전체 전환보다 해당 서비스만 degrade하는 것이 먼저입니다.

노드, AZ 수준인지 클러스터 전체인지 먼저 구분합니다.

범위대응
노드, AZKarpenter 노드 교체, ARC zonal shift로 해당 AZ 우회
drain 중PodDisruptionBudget 없으면 replica가 동시에 빠질 수 있음
클러스터 전체GitOps로 같은 상태인 us-west-2 클러스터를 EKS resource scaling block으로 확장
apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: order-api-pdb spec: minAvailable: 2 selector: matchLabels: app: order-api

Aurora failover는 쓰기부터 멈춘다

1. 쓰기 중지order, payment API 쓰기 차단
→
2. lag 기록AuroraGlobalDBRPOLag로 손실 범위 추정
→
3. failoverus-west-2에서 allow-data-loss
→
4. 쓰기 확인global writer endpoint로 재개
aws rds failover-global-cluster --region us-west-2 \ --global-cluster-identifier shop-global \ --target-db-cluster-identifier "$USW2_ARN" --allow-data-loss
RPO는 0이 아니다
동기화를 기다리지 않으므로 그 순간의 복제 lag만큼 잃습니다. 보통 초 단위입니다.
write fencing은 best effort
old primary가 잠시 쓰기를 받을 수 있어 1단계가 필수입니다. DNS 캐시 TTL은 5초 수준으로 둡니다.
연결 문자열은 그대로
앱이 global writer endpoint를 쓰면 새 primary를 자동으로 가리킵니다. 단 parameter group, alarm은 상속되지 않습니다.

RPO는 상한을 걸고 유실분은 대사한다

항목내용
파라미터rds.global_db_rpo (Aurora PostgreSQL, 초 단위, 최솟값 20초)
동작모든 secondary의 RPO lag이 값을 넘으면 primary 커밋을 멈추고, 하나라도 따라잡으면 재개
관측AuroraGlobalDBRPOLag (ms) 알람으로 상한에 다가가는 것을 먼저 감지
2리전 주의secondary 쪽 parameter group은 기본값 유지: failover 직후 커밋 정지 방지
결정커밋 가용성과 손실 상한 중 무엇을 택할지 결제 담당 팀과 합의
단계내용
스냅샷old primary 회복 시 rds:unplanned-global-failover-... 스냅샷 생성 시도
비교스냅샷을 별도 클러스터로 복원해 새 primary에 없는 마지막 트랜잭션 확인
외부 원장PG 승인 내역과 대조해 주문 레코드 없는 승인 건 처리
재반영DynamoDB Global Tables의 idempotency key로 중복 없이 재처리
항목내용
구성peered cluster 2개 (us-east-1, us-west-2) + witness 리전 (us-east-2)
얻는 것두 리전 모두 쓰기, 동기 커밋으로 RPO 0, failover 명령 불필요
대가쓰기마다 리전 간 왕복, OCC 충돌 재시도, 트랜잭션당 3,000 rows, 10 MiB 한도
적용 범위기존 Aurora 앱 일괄 이관이 아니라 RPO 0이 필수인 원장 테이블부터 검토

입구는 CloudFront 하나로 고정

사용자HTTPS
→
CloudFrontFunction + KeyValueStore
→
Origin group
VPC originus-east-1 internal ALB
VPC originus-west-2 internal ALB
→
EKS리전별 클러스터
읽기: 자동 재시도
primary origin이 오류를 내면 GET, HEAD, OPTIONS 요청은 secondary origin으로 재시도됩니다.
쓰기: 넘어가지 않음
POST, PUT, DELETE는 origin failover 대상이 아닙니다. 활성 리전 값을 KeyValueStore에 두고 Function이 origin group을 고릅니다.
노출 범위
ALB는 internal, 보안 그룹은 CloudFront VPC origin 쪽만 허용합니다. 컴퓨트에 public IP를 두지 않습니다.

전환은 Region switch plan으로

CloudWatch alarm또는 수동 실행
→
Manual approval실행 승인
→
병렬 실행 (us-west-2)
EKS resource scaling
Aurora Global Database
DocumentDB global cluster
Lambda: ElastiCache promote
→
Custom LambdaKVS 활성 리전 변경
활성화 리전에서 실행
Region switch는 리전별 data plane을 두고, 활성화하는 리전에서 plan을 실행합니다. 장애 리전에 의존하지 않습니다.
기본 제공 block
EC2 ASG, ECS, EKS, Aurora Global Database, DocumentDB, Neptune, RDS replica, ARC routing control, Route 53 health check 등.
없는 것은 Lambda로
ElastiCache Global Datastore와 CloudFront KVS 변경은 custom Lambda block으로 넣습니다.

Lambda는 재실행해도 안전하게

import boto3 GDS, RG, REGION = "<global-datastore-id>", "cart-usw2", "us-west-2" ec = boto3.client("elasticache", region_name=REGION) # 승격할 리전 def handler(event, context): g = ec.describe_global_replication_groups(GlobalReplicationGroupId=GDS, ShowMemberInfo=True)["GlobalReplicationGroups"][0] if any(m["ReplicationGroupId"] == RG and m["Role"].lower() == "primary" for m in g["Members"]): return {"status": "already-primary"} # 재실행해도 안전 # Status로 막지 않음: 리전 장애 중에는 available이 아닐 수 있음 ec.failover_global_replication_group( GlobalReplicationGroupId=GDS, PrimaryRegion=REGION, PrimaryReplicationGroupId=RG) return {"status": "failover-started"}
세 파라미터 필수, 상태로 막지 않는다 장애 중에는 Status가 available이 아닐 수 있어 "이미 primary인가"만 확인합니다.

DocumentDB 장애는 failover로

정상 상태의 global cluster에서 primary 리전을 옮깁니다. 훈련, 리전 순환, failover 후 원복에 씁니다.

aws docdb switchover-global-cluster \ --region us-east-1 \ --global-cluster-identifier mall-catalog-global \ --target-db-cluster-identifier arn:aws:rds:us-west-2:<ACCOUNT>:cluster:catalog-usw2

모든 secondary가 동기화될 때까지 기다린 뒤 전환하므로 데이터 손실이 없습니다. 모든 리전의 engine version이 같아야 하고, 역할 전환은 수 분까지 걸릴 수 있습니다.

primary 리전 장애 시 secondary를 승격합니다. 명령은 승격할 리전에서 실행합니다.

aws docdb failover-global-cluster \ --region us-west-2 \ --global-cluster-identifier mall-catalog-global \ --target-db-cluster-identifier arn:aws:rds:us-west-2:<ACCOUNT>:cluster:catalog-usw2 \ --allow-data-loss

실행 전 GlobalClusterReplicationLag(ms)가 가장 작은 secondary를 고릅니다. 보통 1분 안에 승격되며 복제되지 않은 쓰기는 유실될 수 있습니다. 이전 primary는 회복 후 자동으로 secondary로 재합류합니다.

점검 항목내용
writer endpoint바뀜: 앱이 새 endpoint를 쓰는지 확인
parameter group, alarm상속되지 않음: 새 primary에 다시 구성
다른 secondary재구축에 수 분에서 수 시간
유실분rds:docdb-unplanned-global-failover-... snapshot을 수동 snapshot으로 복사
원복원래 리전 회복 후 switchover로 수행

cart 캐시는 사람이 승격한다

1. 쓰기 차단cart API read-only
→
2. promote 실행us-west-2를 primary로
→
3. endpoint 전환앱 설정 갱신
→
4. 재합류 확인이전 primary는 secondary
aws elasticache failover-global-replication-group \ --global-replication-group-id <global-datastore-name> \ --primary-region us-west-2 \ --primary-replication-group-id cart-usw2
자동 failover 없음
Global Datastore는 리전 장애 시 스스로 승격하지 않습니다. 승격은 보통 1분 미만입니다.
전환 중 cart
secondary는 읽기 전용이라 담기, 수정이 실패합니다. 클라이언트에서 재시도 큐로 받습니다.
유실 대비
복제 지연은 보통 1초 미만. 마지막 변경분은 세션 쿠키나 주문 DB에서 재구성합니다.

로드맵: 데이터 먼저, 자동화 다음

P0 데이터 보호
  • MSK Replicator 구성 (us-west-2), consumer offset 동기화
  • Aurora RPO lag 알람, rds.global_db_rpo 정책, global writer endpoint 적용
  • failover 유실분 대사 절차 (스냅샷, PG 승인 대조)
P1 전환 자동화
  • Region switch plan: 승인, EKS scaling, Aurora Global DB, DocumentDB block
  • custom Lambda: ElastiCache promote, CloudFront KVS 변경
  • 전 서비스 PodDisruptionBudget
P2 검증 루프
  • 분기별 FIS 훈련과 Region switch 리허설
  • Resilience Hub 평가를 CI/CD에 연결
  • 실측 RTO/RPO로 목표표 갱신
  • RPO 0 필수 테이블은 DSQL multi-Region 검토
숫자는 비워 둔다 "자동화로 RTO 2분" 같은 목표는 P2 훈련에서 잰 값으로 채웁니다.

훈련 없는 DR은 가설일 뿐

FIS scenario library의 시나리오로, 한 AZ의 전원 손실 증상을 주입합니다.

항목내용
대상EC2 (EKS, ECS 노드 포함), EBS, ASG, 서브넷, ElastiCache, RDS
용량 제약 재현지정한 IAM role, ASG의 새 인스턴스 시작을 막아 "용량 확보 실패"까지 시험
관찰 지표Karpenter 노드 교체, zonal shift, DB writer 이동 시간
주기 (예시)월 1회 비운영, 분기 1회 운영: 조직 기준으로 조정

실험 리전에서 대상 리전으로 가는 트래픽을 막고 복제를 멈춥니다. 기본 지속 시간 3시간(disruptionDuration).

Action효과
aws:network:route-table-disrupt-cross-region-connectivity서브넷의 대상 리전 경로 차단
aws:network:transit-gateway-disrupt-cross-region-connectivityTGW 경유 트래픽 차단
aws:s3:bucket-pause-replicationS3 복제 일시 정지
aws:dynamodb:global-table-pause-replicationGlobal Table 복제 정지

AWS 관리형 서비스 트래픽은 막히지 않을 수 있습니다. DocumentDB, ElastiCache 복제는 이 시나리오로 끊기지 않으니 별도로 검증합니다.

단계내용
실행분기 1회 plan을 실제로 실행해 us-west-2로 전환, switchover로 원복
측정감지까지, 승인까지, 전환 완료까지 시간과 유실 데이터
장애 중 전환FIS로 장애를 주입한 상태에서 plan 실행
회고PIR로 기록하고 Runbook과 plan을 함께 갱신
기능내용
Resiliency policyApplication, Infrastructure, Availability Zone, Region별 RTO/RPO 목표
Assessment구성 요소를 분석해 목표 충족, 위반과 추정 RTO/RPO 표시
Recommendations개선안별 예상 RTO, RPO, 비용과 alarm, FIS 실험, SOP 제안
CI/CD 연동구성 변경이 목표를 깨는지 배포 전에 확인

Key Takeaways

1. 기본은 단일 writer
지금은 전부 단일 writer Warm Standby. RPO 0이 필수인 테이블만 DSQL Active/Active를 검토합니다.
2. 가장 약한 고리가 RTO, RPO
MSK Replicator가 없으면 DB가 넘어가도 이벤트는 남습니다. Aurora failover는 lag만큼 잃고 rds.global_db_rpo로 상한을 둡니다.
3. 엣지는 읽기만 자동
CloudFront origin failover는 GET, HEAD, OPTIONS만. 쓰기는 KVS의 활성 리전 값으로 전환합니다.
4. 전환은 plan으로
Region switch는 활성화 리전에서 실행됩니다. 기본 block이 없는 단계는 멱등 Lambda로 채웁니다.
5. 명령을 구분
Aurora, DocumentDB 장애는 쓰기 중지 후 failover + allow-data-loss, 계획 전환과 원복은 switchover. ElastiCache는 수동 promote.
6. 숫자는 훈련으로
FIS 시나리오와 Region switch 리허설로 실측한 RTO/RPO만 목표표에 씁니다.

Knowledge Check

Q1: us-east-1 장애 시 DocumentDB global cluster를 us-west-2로 넘기는 올바른 방법은?
Q2: CloudFront origin group이 secondary origin으로 재시도하는 요청은?
Q3: us-east-1 장애로 Aurora Global Database를 failover했을 때 맞는 설명은?

Thank You

Block 4: DR & Failover Automation 완료

← 목차로 돌아가기 다음: Observability & Operations →