1차 마이그레이션 리허설 시나리오 - 100-hours-a-week/KTB4-4th-wiki GitHub Wiki

1. 리허설 목적

이번 리허설은 현재 운영 중인 V1 구조를 V2 ECS 기반 구조로 전환하기 전에, 실제 전환 과정과 서비스 연속성을 Staging에서 미리 검증하는 작업이다.

단순히 V2 서버가 실행되는지만 확인하는 것이 아니라 다음 내용을 함께 확인한다.

  • V1의 MySQL 및 PostgreSQL 데이터를 V2로 안전하게 이전할 수 있는지
  • 데이터 이전 중 발생하는 쓰기 차단 시간을 측정할 수 있는지
  • DNS를 V1에서 V2로 바꾸는 동안 조회 요청이 계속 처리되는지
  • 문제가 생겼을 때 DNS를 다시 V1으로 돌려 서비스가 복구되는지

1차 리허설에서는 전환 과정 자체를 검증하는 데 집중한다. 전환 후 V2에서 새로운 데이터를 쓰는 시나리오는 포함하지 않으며, 조회 요청을 기준으로 서비스 연속성을 확인한다.

2. 도메인의 역할

리허설에는 다음 세 주소를 사용한다.

주소 역할
v1.needu.gift V1 Staging에 직접 접속하는 주소
v2.needu.gift V2 Staging에 직접 접속하는 주소
staging.needu.gift 리허설 중 사용자가 접속하는 공통 주소

리허설 시작 시 staging.needu.gift는 V1을 가리킨다. V2 준비와 데이터 검증이 끝나면 이 주소만 V2로 변경한다.

따라서 클라이언트와 테스트 도구는 같은 주소를 계속 사용하고, 인프라에서 연결 대상만 V1에서 V2로 전환한다. 문제가 발생하면 같은 방식으로 staging.needu.gift를 다시 V1으로 되돌린다.

3. 리허설 전 상태

  • V1 Staging은 V1 운영 환경과 같은 애플리케이션 이미지를 사용한다.
  • V1 운영 데이터를 V1 Staging DB에 복제해 실제와 유사한 데이터 상태를 준비한다.
  • V2 Staging 인프라는 Terraform으로 생성하지만, 데이터 이전이 끝나기 전까지 ECS 서비스는 실행하지 않는다.
  • V1과 V2에서 필요한 런타임 설정은 서로 분리된 SSM 경로로 관리한다.
  • 테스트 계정의 기존 JWT로 전환 전후의 조회 요청을 확인할 수 있도록 V1 Staging의 JWT Secret을 V2 Staging에도 사용한다.

4. 데이터 이전 방식

MySQL

MySQL은 AWS DMS의 Full Load + CDC 방식으로 이전한다.

  1. Full Load로 V1 Staging의 기존 데이터를 V2 Staging RDS에 복제한다.
  2. Full Load 이후에도 V1에서 발생하는 변경 사항을 CDC로 계속 V2에 반영한다.
  3. 최종 전환 시 V1의 쓰기를 차단한다.
  4. 남아 있던 변경 사항이 모두 V2에 반영되어 CDC 지연이 0에 가까워졌는지 확인한다.
  5. 데이터 건수와 주요 테이블의 값을 비교한 뒤 DMS 복제를 종료한다.

이 방식은 전체 데이터를 복사하는 동안 V1을 계속 사용할 수 있게 하고, 실제 쓰기 중단 시간을 마지막 동기화 구간으로 줄이기 위한 것이다.

PostgreSQL

PostgreSQL은 pg_dump와 pg_restore 방식으로 이전한다.

V1 Staging PostgreSQL의 상품 문서, 분류 정보, 임베딩 데이터를 백업한 뒤 V2 Staging PostgreSQL에 복원한다. 현재 데이터는 Catalog Sync만으로 동일하게 재생성할 수 없으므로, 이번 리허설에서는 기존 데이터 자체를 옮기는 방식을 사용한다.

복원이 완료되면 AI 서비스와 Catalog 작업이 사용할 읽기·쓰기 계정 및 접속 정보를 V2 Staging 기준으로 구성한다.

5. 인증과 세션 처리

Backend는 Access Token 인증 시 다음 정보를 검증한다.

  • JWT 서명이 올바른지
  • 토큰이 만료되지 않았는지
  • 토큰에 userId 클레임이 포함되어 있는지

API 요청마다 MySQL의 auth_sessions나 Redis의 로그인 세션을 조회하지는 않는다.

따라서 다음 조건을 충족하면 V1 Staging에서 발급한 테스트 계정의 Access Token을 V2에서도 사용할 수 있다.

  • V1 Staging과 V2 Staging이 동일한 JWT Secret을 사용함
  • Access Token이 만료되지 않음
  • 토큰의 userId에 해당하는 사용자가 V2 DB에도 존재함

현재 V1 Staging의 auth_sessions는 이미 비어 있으므로, 로그인 세션을 V2로 옮겼다가 삭제하는 과정은 수행하지 않는다. MySQL 데이터 복제 후 V2의 auth_sessions도 비어 있는지만 확인한다.

리허설에서는 다음 방식으로 인증 연속성을 검증한다.

  1. V1 Staging에서 테스트 계정 20개의 유효한 Access Token을 준비한다.
  2. V1 Staging API에서 해당 토큰으로 조회 요청이 정상 처리되는지 확인한다.
  3. 테스트 계정을 포함한 사용자 데이터를 V2 MySQL로 복제한다.
  4. V1 Staging과 V2 Staging에 동일한 JWT Secret을 적용한다.
  5. DNS 전환 전후에 같은 Access Token으로 조회 요청을 계속 보낸다.
  6. V2에서도 기존 Access Token이 정상 인증되는지 확인한다.

Access Token이 만료되면 새 로그인이 필요하므로, 리허설 시작 직전에 테스트 토큰의 만료 시간을 확인하거나 새로 발급한다.

6. V2 서비스 기동 순서

데이터 준비 상태에 따라 V2 서비스를 다음 순서로 실행한다.

  1. DB를 직접 사용하지 않는 Frontend를 먼저 시작한다.
  2. PostgreSQL 복원과 AI 설정이 끝나면 AI를 시작한다.
  3. V1 Write Freeze 후 MySQL CDC와 데이터 정합성 검증을 완료한다.
  4. MySQL을 사용하는 Backend를 마지막으로 시작한다.
  5. 모든 서비스의 Health Check를 확인하고 v2.needu.gift에서 Smoke Test를 진행한다.

V2의 정상 동작을 확인한 후 staging.needu.gift를 V1에서 V2로 전환한다.

7. Write Freeze와 최종 동기화

DNS 전환 직전 V1 Staging에 Write Freeze를 적용한다.

Write Freeze 시작 전에 테스트 계정 20개의 Access Token을 준비하고 k6 조회 테스트를 시작한다. Write Freeze 동안에는 새 로그인, 토큰 재발급, 카카오 콜백 및 데이터 변경 요청을 Nginx에서 차단하고 503 Service Unavailable을 반환한다. 이미 발급된 Access Token을 사용하는 친구·추천 조회 API는 계속 허용한다.

새로운 쓰기가 차단되면 다음 작업을 진행한다.

  1. 진행 중인 쓰기 요청과 DB 트랜잭션이 종료될 때까지 기다린다.
  2. DMS CDC가 마지막 변경 사항까지 반영됐는지 확인한다.
  3. DMS 오류 여부와 주요 MySQL 테이블의 행 수 및 핵심 데이터를 V1·V2에서 비교한다.
  4. PostgreSQL의 상품·설명·임베딩 데이터 건수를 비교한다.
  5. auth_sessions가 V1·V2 모두 비어 있는지 확인한다.
  6. V2 Backend를 시작하고 전체 서비스의 Health Check를 확인한다.
  7. 같은 테스트 Access Token으로 V2 조회 API가 정상 동작하는지 확인한다.

DMS 상태, 데이터 비교 결과와 확인 시각은 리허설 결과 자료로 보관한다.

Write Freeze 시작부터 V2로 정상적인 트래픽이 들어오는 시점까지를 실제 전환 중단 시간으로 측정한다.

8. 트래픽 검증과 DNS 전환

k6는 테스트 계정 20개의 JWT를 사용해 staging.needu.gift로 초당 10건의 읽기 요청을 지속해서 보낸다.

주요 검증 대상은 다음과 같다.

  • 친구 목록 조회
  • 친구 상세 조회
  • 개인 추천 조회
  • 선물 추천 조회

전환 전에는 요청이 V1에서 처리된다. V2 직접 주소의 기능과 데이터 정합성이 확인되면 Route 53에서 staging.needu.gift의 연결 대상을 V2 ALB로 변경한다.

DNS 변경 후에는 단순히 주소 응답만 확인하지 않고 다음 사항을 함께 확인한다.

  • V2 ALB Access Log와 애플리케이션 로그에 실제 요청이 들어오는지
  • k6 요청의 성공률과 응답 시간이 유지되는지
  • ALB 4xx·5xx 및 Target Health에 이상이 없는지
  • ECS Task 재시작이나 CPU·Memory 급증이 없는지
  • RDS 연결 수와 오류에 이상이 없는지

9. 모니터링 방식

리허설의 기본 관측 화면은 Grafana로 통합한다.

  • Loki: V1·V2 애플리케이션 및 프록시 로그 확인
  • Prometheus: k6와 애플리케이션 지표 수집
  • AWS 지표: ALB, ECS, RDS, ElastiCache, DMS 상태 확인
  • Grafana: 로그, 부하 테스트 결과 및 AWS 지표를 한 화면에서 비교

로그에는 environment, version, service 구분값을 두어 동일한 요청 시간대의 V1과 V2 상태를 구분해서 확인할 수 있게 한다.

CloudWatch Logs와 기존 배포 알람은 AWS 측 안전장치로 유지하되, 리허설 판단과 분석은 Grafana를 중심으로 진행한다.

10. 롤백 시나리오

DNS 전환 후 오류율 증가, 데이터 불일치 또는 핵심 기능 장애가 발견되면 즉시 롤백한다.

  1. staging.needu.gift의 연결 대상을 다시 V1으로 변경한다.
  2. V1 ALB 또는 EC2에 실제 트래픽이 돌아왔는지 확인한다.
  3. k6 읽기 요청이 V1에서 정상 처리되는지 확인한다.
  4. V1 복구가 확인된 뒤 Write Freeze를 해제한다.
  5. V2 ECS 서비스를 정지하고 장애 원인을 분석한다.

1차 리허설에서는 V2 전환 후 쓰기 요청을 허용하지 않으므로 V2에서 새로 생성된 데이터를 V1으로 역동기화하지 않는다. 이 제한 덕분에 DNS만 되돌려 비교적 단순하고 안전하게 롤백할 수 있다.

11. 리허설 성공 판단

다음 조건을 충족하면 1차 리허설이 성공한 것으로 판단한다.

  • MySQL Full Load와 CDC가 정상 완료됨
  • PostgreSQL 데이터가 V2에 정상 복원됨
  • V1과 V2의 주요 데이터 정합성이 확인됨
  • Write Freeze 동안 읽기 요청이 유지됨
  • 기존 테스트 JWT가 V2에서도 정상 인증됨
  • DNS 전환 후 요청이 실제로 V2에서 처리됨
  • k6 요청에서 유의미한 오류율 증가가 없음
  • V2의 ALB, ECS, RDS 및 애플리케이션 상태가 정상임
  • 전환 소요 시간과 각 단계의 관측 결과를 기록함
  • 장애 발생 시 V1으로 되돌리는 절차가 정상 동작함

이번 결과를 바탕으로 2차 리허설에서는 쓰기 요청, V2에서 발생한 데이터의 처리 방식, 운영 전환 시 승인 기준 및 더 구체적인 롤백 기준을 보완한다.