AWS 기술 블로그
Amazon Aurora Blue/Green Deployment를 활용하여 애플리케이션 계층을 포함한 데이터베이스 변경 사전 테스트하기
이 글은 애플리케이션 계층을 포함한 데이터베이스 변경 사전 테스트의 중요성과 사전 테스트를 위한 아키텍처를 소개합니다. 특히 Amazon Aurora의 Blue/Green Deployment를 핵심으로 CQRS(Command Query Responsibility Segregation) 패턴과 Amazon Route53의 트래픽 흐름(Traffic Flow)과 트래픽 정책(Traffic Policy)을 활용한 아키텍처를 다룹니다.
Amazon Aurora는 MySQL 및 PostgreSQL과 호환되는 완전 관리형 관계형 데이터베이스이며, 일반적인 데이터베이스 유지보수 작업(백업 및 복구, 패치 등)은 자동화됩니다. 하지만 버전 업그레이드의 경우에는 완전 관리형 데이터베이스를 사용하더라도 업그레이드 계획, 테스트 및 운영 전환과 같은 고도의 작업 계획 수립이 필요합니다. 또한 파티셔닝, 스키마 변경과 같은 데이터베이스 변경 작업을 수행할 때에도 동일하게 변경 계획, 테스트와 같은 과정을 거치게 됩니다. 특히 이 과정에서 사전 테스트는 안정성 측면에서 중요도가 매우 높으며, 사전 테스트를 통해 확인한 문제 상황들은 사전 계획 수립 시에 도움이 될 뿐만 아니라, 사후 계획에도 영향을 미칠 수 있습니다. 또한 사전 테스트 수행 결과는 변경 작업의 수행 이후에 모니터링 할 특정 지표 및 상황에 대한 우선순위를 정하는데 도움을 줍니다.
이런 중요함에도 불구하고, 데이터베이스에 대한 변경을 수행할 때 작업 관계자들에게 가장 난해한 과정은 단연 사전 테스트입니다. 일반적으로 사전 테스트는 개발/스테이징 환경에서 진행하지만, 이는 프로덕션 환경과 상이할 가능성이 높습니다. 테스트 환경의 큰 차이로 인해 테스트 수행자는 실효성에 의문을 가지기도 합니다. 그렇다고 사전 테스트 없이 프로덕션 환경에 변경을 적용하는 것은, 예측할 수 없는 다운 타임과 대규모 문제 상황을 발생시킬 수 있으며, 이는 당연히 안정성 측면에서 권장되지 않습니다. 따라서 데이터베이스 변경 결정권자와 테스트 수행자 모두 이와 같은 간극 속에서 안전한 사전 테스트 방법론을 고민하게 됩니다.
또한 이러한 데이터베이스 변경을 위한 사전 테스트는, 일반적으로 데이터베이스 관리자(DBA)의 역할로 여겨지는 경향이 크며, 자연스럽게 개발자는 사전 테스트 논의에서 소외되기도 합니다. 하지만 Object-Relational Mapping (ORM)의 영향으로 인해 현대의 백엔드 애플리케이션 계층은 데이터베이스 계층과 더욱 긴밀하게 연결되는 경향이 있습니다. 이는 백엔드 애플리케이션 개발자도 데이터베이스 변경이 애플리케이션에 미치는 영향을 이해하고, 서비스/애플리케이션 레벨의 더 적은 다운 타임과 장애 대응을 위해, 데이터베이스 변경을 사전에 대비해야 할 필요성을 발생시켰습니다. 따라서 데이터베이스 변경 사전 테스트에 있어 데이터베이스 관리자의 역할도 매우 중요하지만, 백엔드 애플리케이션 개발자의 역할과 애플리케이션 계층 사전 테스트에 대한 중요도도 높아졌습니다.
정리해보면 데이터베이스 변경 사전 테스트 수행자들은 다음과 같은 어려움을 겪습니다.
- 개발/스테이징 환경과 프로덕션 환경의 간극, 즉 안전성과 현실성 사이의 트레이드 오프로 인한 어려움
- 애플리케이션 계층과 데이터베이스 계층의 긴밀한 연결에 따른 테스트 범위/관계자 증대
본 글은 위의 어려움을 해결하기 위해서, 다음의 조건들을 만족하는 서로 보완 가능한 아키텍처 2개를 제안합니다.
- 프로덕션 환경의 트래픽을 활용하여 테스트를 수행
- 가능한 안전하게 테스트를 수행
- 애플리케이션 계층을 포함한 테스트를 수행
또한 제안된 두 개의 아키텍처는 동시에 적용될 수도 있으며, 워크로드 특성에 따라 유연하게 하이브리드 방식으로 각 아키텍처의 일부만 적용될 수 있습니다.
사전 준비
애플리케이션 계층을 포함한 데이터베이스 변경 사전 테스트 아키텍처들의 기반이 되는 AWS 기능과 개념에 대한 간단한 알아보겠습니다.
블루/그린 배포(Blue/Green Deployment)
가장 핵심적인 기능인 블루/그린 배포는 클릭 몇 번 만으로 쉽고 간단하게, 기존 운영 데이터베이스 클러스터인 블루와 이를 복제한 그린 데이터베이스 클러스터 간의 바이너리 로그 복제(binary log replication)을 자동으로 구성해주며, 데이터베이스 전환(switchover) 시에도 클러스터 엔드포인트가 변경되지 않으므로 별도의 애플리케이션 배포가 필요 없다는 장점이 있습니다. 따라서 2가지 아키텍처 모두에서 블루/그린 배포를 활용하며, 그린 데이터베이스 클러스터를 구성하여 데이터베이스 변경 수행 후의 사전 테스트를 진행하게 됩니다.
데이터베이스 변경 전 애플리케이션 포함 사전 테스트의 중요성
데이터베이스 변경에 관한 사전 테스트는 애플리케이션에 대한 검증도 포함하여 이루어져야 합니다. 위에서 설명한 것처럼 현대의 서비스를 지탱하는 애플리케이션 계층은 이전에 비해 훨씬 빠르고 잦은 변경을 수행하고 있으며, 이 과정에서 애플리케이션 계층의 객체와 데이터베이스 계층의 관계가 긴밀하게 연결되는 ORM을 활용하는 경우가 많아졌습니다. ORM을 사용하지 않고 계층 분리를 통해 서로 간의 커플링을 제거하기도 하지만, 여전히 데이터베이스 변경은 애플리케이션 성능을 비롯해 쿼리 결과의 변경 등, 데이터베이스 관리자와 백엔드 애플리케이션 개발자 모두 예상하지 못한 이슈를 일으킬 가능성이 매우 높습니다. 사전 테스트 과정에서 부서 간 협의로 인한 커뮤니케이션 비용과 사전 테스트를 진행하는 비용 등의 사전 테스트 수행 비용이 발생할 수 있습니다. 하지만, 이는 변경 후 대규모 서비스 장애가 발생하거나 이에 대응하는 비용보다 훨씬 적은 비용이기 때문에, 애플리케이션 계층을 포함한 사전 테스트를 수행하는 것을 권장 드립니다.
예를 들어, 다음과 같은 간단한 스키마를 가지고 있는 서비스에서 “description” 이라는 컬럼을 삭제하는 변경을 데이터베이스에서 수행했다고 가정해보겠습니다.
이후 ORM을 사용하고 있는 애플리케이션 계층에서는 “Unknown column“과 같은 에러 로그를 남기고 API 응답을 하지 못 하는 장애 상황이 발생하게 됩니다. 이처럼 데이터베이스 계층에서 단순한 스키마 변경이라고 여겼더라도 언제나 해당 변경으로 인해 애플리케이션 계층에 영향을 미칠 수 있습니다. 따라서 데이터베이스 계층의 변경이 잦거나 애플리케이션 계층과의 커플링이 복잡한 상황에서, 애플리케이션 계층에 어떤 영향을 미칠지는 사전 테스트 없이는 예상하기 어려우며, 이는 애플리케이션 계층이 크고 복잡할수록 훨씬 더 어렵습니다. 즉, 데이터베이스 변경이 일어난다면 애플리케이션 계층을 포함한 사전 테스트가 반드시 함께 이루어져야 합니다.
읽기/쓰기 트래픽의 분리
다음으로, 테스트 방법론에서 가장 중요한 개념인 “읽기/쓰기 트래픽의 분리”입니다. 만약 읽기/쓰기 트래픽의 분리 없이, 블루 데이터베이스 클러스터와 그린 데이터베이스 클러스터에 쓰기 트래픽이 나누어져 처리되었다고 가정해보겠습니다. 블루 데이터베이스 클러스터와 그린 데이터베이스 클러스터에 같은 항목에 대해 각각 다른 쓰기가 이뤄졌다면, 두 클러스터 간의 데이터 일관성이 깨지거나 클러스터 간 데이터 오염이 발생하게 됩니다. 따라서 이런 문제를 피하기 위해 쓰기 트래픽은 블루 데이터베이스 클러스터에만 전달되어야 하며, 해당 조건을 만족하기 위해 읽기/쓰기 트래픽은 분리 되어야 합니다.
예를 들어, 아래와 같이 동일한 스키마를 가지고 있으며 논리적 복제가 이루어지고 있는 상황에서 쓰기 트래픽이 블루 클러스터와 그린 클러스터 각각에 흘러들어갔다고 가정해보겠습니다.
일반적인 워크로드에서 사용자는 두 개의 변경 요청이 모두 순차적으로 또는 최종적으로 반영이 되어, 정확성과 일관성이 반영이 된 결과값을 읽어오기를 기대하게 됩니다. 하지만 실제로는 아래의 상황들처럼 사용자의 기대와 다른 결과가 발생할 수 있습니다.
상황 1. 사용자는 특정 요청/쿼리가 미적용된 결과 값을 읽게 됩니다. 블루 환경에 적용된 내용이 그린 환경에 적용한 내용을 덮어쓰기 했기 때문에 100 빼기라는 요청이 적용되지 않았습니다.
상황 2. 각 데이터베이스에 따로 각 요청이 반영 되었으며 읽어온 시점에 서로 다른 값을 가지고 있습니다.
즉, 사전 테스트 시 애플리케이션 계층 혹은 인프라 계층에서 읽기/쓰기 트래픽 분리는 높은 우선순위로 고려되어야 하며, 특히 프로덕션 트래픽을 활용하는 사전 테스트 아키텍처라면 쓰기 트래픽은 신중하게 다뤄져야 합니다. 또한 앞의 내용에서 강조한 것처럼 이와 같은 문제 상황 파악을 위해 실제 서비스와 흡사하게 애플리케이션 계층을 포함한 사전 테스트가 필수적입니다.
참고로 읽기/쓰기 트래픽 분리에 관한 각 사전 테스트 아키텍처의 가정은 다음과 같습니다.
- CQRS를 활용한 아키텍처는 애플리케이션 계층에서 읽기/쓰기 트래픽에 대한 분리, 즉 애플리케이션 레벨의 CQRS 패턴이 구현되어 있다는 것을 가정하고 있습니다.
- Route53의 트래픽 흐름(Traffic Flow)과 트래픽 정책(Traffic Policy)을 활용한 아키텍처는 인프라 계층에서 읽기/쓰기 트래픽이 분리되어 있다는 것을 가정하고 있습니다.
솔루션 개요
애플리케이션 계층을 포함한 데이터베이스 변경 사전 테스트 아키텍처들을 알아보도록 하겠습니다.
CQRS 패턴을 활용한 아키텍처
CQRS 패턴
CQRS 패턴은 명령과 쿼리, 즉 쓰기와 읽기를 분리하여 각 액세스 패턴에 따른 데이터 스토어를 설정할 수 있게 하는 아키텍처 패턴입니다. 다만 서로 다른 데이터 스토어를 사용하게 된다면 스케일링, 지연 시간 및 일관성에 대해서 고려해야 합니다. 관련하여 보다 자세한 내용은 CQRS 패턴을 참고하시는 것을 권장드립니다.
아키텍처
해당 아키텍처는 CQRS 패턴이 사전에 애플리케이션 계층에 적용되어 있으며 읽기/쓰기에 동종 데이터 스토어로 Aurora를 사용하는 구조입니다. 관련해서 두 데이터베이스의 생성 및 데이터베이스 간 복제도 블루/그린 배포를 통해 자동으로 구성합니다. 쓰기 트래픽 처리를 위한 애플리케이션의 데이터 계층은 블루 데이터베이스 클러스터에 연결하며, 읽기 트래픽 처리를 위한 애플리케이션의 데이터 계층은 그린 데이터베이스 클러스터에 연결합니다. 단, 데이터 일관성을 지키고 데이터 오염을 방지하기 위해 그린 데이터베이스 클러스터는 읽기 전용(Read-only) 엔드포인트를 활용하여 읽기 전용 트래픽만 전달되어야 합니다.
다음은 해당 아키텍처의 장점과 단점입니다.
- 장점
- 읽기와 쓰기 요청을 인프라 계층에서 분리할 필요가 없으며, 인프라 계층의 변경이 크게 발생하지 않습니다.
- 그린 데이터베이스 클러스터에 대한 비용 외에 추가적인 비용이 발생하지 않습니다.
- 단점
- 애플리케이션 계층에서 CQRS 패턴 적용 혹은 읽기/쓰기 엔드포인트가 사전에 분리되어 있어야 시도할 수 있습니다. 기존에 Aurora의 읽기 엔드포인트를 활용하고 있다면 해당 아키텍처 적용의 난이도가 낮으며 애플리케이션 재배포를 통해 읽기 엔드포인트를 블루 클러스터로 변경하여 롤백할 수 있습니다.
- 에러가 발생한다면 프로덕션 레벨의 읽기에서 장애가 발생할 수 있습니다. 단, 애플리케이션 계층 배포 전략(카나리, 롤링)을 통해 짧은 시간동안 그린 데이터베이스 클러스터와 연결되어 있는 일부 애플리케이션 인스턴스/컨테이너에 일부 트래픽을 전달하며 장애 확인 후 롤백을 시도하면 전체 읽기 장애 상황을 방지할 수 있습니다.
- 테스트를 위해 읽기 엔드포인트 변경이 필요하며 이로 인해 기존 애플리케이션 재배포가 필요합니다.
Route53 트래픽 흐름과 트래픽 정책을 활용한 아키텍처
Route 53 트래픽 흐름과 트래픽 정책 활용의 장단점
Route53 트래픽 흐름은 크고 복잡한 구성에서 레코드를 생성하고 유지 관리하는 프로세스를 대폭 간소화할 수 있는 도구입니다. 또한 시각적 편집기 사용자 인터페이스를 통해 간편하게 설정하고 팀 내에 트래픽 흐름 및 정책을 공유할 수 있습니다.
Route53 트래픽 정책은 여러 레코드 간의 관계를 설정하고 각 레코드의 구성을 쉽게 생성할 수 있도록 도와주며, 각 트래픽 정책의 버전을 활용해 관리할 수 있게 도와줍니다. 트래픽 정책은 프라이빗 호스팅 영역(Private Hosted Zone)도 지원하기 때문에, 인터넷으로 노출되어 있는 도메인을 사용하고 싶지 않은 상황이거나 마이크로 서비스 아키텍처(Micro Service Architecture, MSA)에서 인터넷을 거치지 않고 다른 서비스에 대해 트래픽을 전달해보고 싶은 상황에 충분히 활용할 수 있습니다.
단, 트래픽 분배를 위해 Route53 트래픽 정책을 활용하여 사전 테스트하게 된다면 쓰기 트래픽에 대한 테스트를 진행하는 것은 매우 어렵습니다. 블루와 그린 환경에 각기 다른 쓰기 트래픽이 전달된다면 일반적으로 데이터 일관성이 깨지게 됩니다. 따라서 Route53 트래픽 정책을 활용하여 테스트를 진행하시게 된다면 읽기 전용(Read-only) 트래픽만 전달하여 테스트하는 것을 권장드립니다.
아키텍처
해당 아키텍처는 애플리케이션 계층을 하나 더 실행시켜 Route53의 트래픽 정책을 활용해 2개의 환경에 가중치를 주어 트래픽을 분산하여 테스트하는 구조입니다. CQRS 패턴을 활용한 아키텍처와 동일하게 두 데이터베이스의 생성 및 데이터베이스 간 복제는 블루/그린 배포를 통해 자동으로 구성합니다. 중요한 것은 읽기 전용 트래픽만 Route53을 통해 전달되어야 한다는 점입니다. 가중치를 활용해 일부 쓰기 트래픽을 그린 환경에 전달하게 되면 위에 서술한 내용처럼 데이터 일관성 및 오염으로 인한 문제가 발생할 수 있습니다.
다음은 해당 아키텍처의 장점과 단점입니다.
- 장점
- 기존 애플리케이션을 변경하지 않아도 되며, 그린 데이터베이스 변경에 따른 애플리케이션 변경을 빈번하게 수행하는 상황에서도 트래픽 가중치를 조절하여 기존 애플리케이션/서비스에 영향이 가지 않도록 설정할 수 있습니다.
- Route53 트래픽 정책을 활용하여 테스트하고 싶은 트래픽의 비율을 클릭 몇 번으로 변경할 수 있습니다. 특히 그린 환경의 변경 작업 수행 전에 블루 환경에 100%의 트래픽을 전달하도록 변경하여 프로덕션 레벨의 장애를 막을 수 있습니다.
- 추가 애플리케이션 스택을 통해 용량을 탄력적으로 조정할 수 있기 때문에, 필요하다면 프로덕션 트래픽을 처리하며 스트레스 테스트를 진행할 수 있습니다.
- 단점
- 그린 데이터베이스 클러스터로 전달되는 트래픽에 쓰기 트래픽이 포함되어 있다면 이는 큰 장애로 이어질 수 있습니다. 단, 그린 데이터베이스 클러스터에 연결할 때 읽기 엔드포인트를 사용한다면 데이터 일관성과 오염으로 인한 문제를 방지할 수 있습니다. 그러나 일정 비율의 쓰기 트래픽이 실패할 수 있습니다.
- 만약 RESTful API로 애플리케이션 계층이 구성되어 있다면, 추가 Application Load Balancer(ALB)를 활용하여 요청 HTTP 메소드(GET, POST, PUT, DELETE 등)에 따라 읽기/쓰기 트래픽을 분리할 수도 있습니다.
- Route 53의 트래픽 정책, 그린 데이터베이스 클러스터와 추가적인 애플리케이션 인스턴스/컨테이너로 인해 테스트 비용이 증가할 수 있습니다.
- 그린 데이터베이스 클러스터로 전달되는 트래픽에 쓰기 트래픽이 포함되어 있다면 이는 큰 장애로 이어질 수 있습니다. 단, 그린 데이터베이스 클러스터에 연결할 때 읽기 엔드포인트를 사용한다면 데이터 일관성과 오염으로 인한 문제를 방지할 수 있습니다. 그러나 일정 비율의 쓰기 트래픽이 실패할 수 있습니다.
결론
소개한 두 가지 아키텍처를 기반으로 블루/그린 배포, CQRS 패턴과 Amazon Route53을 활용하여 프로덕션 환경에서 데이터베이스 계층과 애플리케이션 계층에 걸쳐 안정적이고 현실적으로 테스트할 수 있는 방법을 확인하였습니다. 현대의 서비스에서 데이터베이스와 애플리케이션을 담당하는 데이터베이스 관리자와 개발자는, 한 팀으로 변경에 대한 책임을 가지고 사전 테스트를 수행할 필요가 있습니다. 이번 블로그를 통해 애플리케이션 계층을 포함한 사전 테스트의 중요성과 어려움, 테스트 아키텍처들의 장단점을 안내했으며 유연하게 적용할 수 있는 적절한 지침을 제공했습니다.
마지막으로 Route53 가중치 기반 레코드와 커스텀 읽기 엔드포인트를 활용한 테스트 방법에 대해 궁금하시다면, 테크니컬 어카운트 매니저 이아영님과 김학신님이 작성하신 Amazon RDS MySQL 블루/그린 배포 환경에서 Amazon Route 53을 활용한 운영환경 읽기 쿼리 분산을 읽어보시는 것을 추천드립니다.