AWS 기술 블로그

Amazon RDS Proxy 를 이용한 스푼라디오 서비스 무중단 변경

SpoonRadio는 “Connect the world with people’s stories” 라는 목표를 갖고 한국, 일본, 미국, 대만 등 총 21개국, Global User 20M 명에게 서비스 하고 있습니다.

SpoonRadio는 누구나 편하게 목소리로 소통할 수 있는 소셜 플랫폼으로 탄생 하였고, 소통과 더불어 많은 즐길거리를 만들어 DJ 와 청취자 사이의 관계를 넘어 서로 긴밀한 관계가 유지 되도록 새로운 시도를 지속하고 있습니다.

SRE 팀 소개

SpoonRadio의 모든 서비스는 약 70개가 넘는 AWS 서비스를 사용하여 구성 및 운영을 하고 있습니다. SRE 팀은 SpoonRadio를 운영하는 모든 AWS 서비스를 관리 / 운영을 담당하고 있으며, 그 중에는 AWS Database Services도 포함 되어있습니다.

AWS 서비스들은 하나의 팀에서만 담당하는 것이 쉽지 않기 때문에 DB를 운영하는 DBA 파트에서는 팀내의 다양한 경험을 하신 DevOps 팀원분들과 협업하여 Database 서비스들이 안전하게 운영할 수 있도록 노력하고 있습니다.

Part 1. Amazon Aurora PostgreSQL의 Spec Down은 왜 필요 하였나?

서비스 증가와 더불어 데이터의 양도 꾸준하게 증가하여, 클라우드 사용 비용도 비례하여 증가되게 됩니다. 이러한 이슈 대응을 위한 FinOps가 활발하게 논의되고 있습니다.

SpoonRadio 역시 이러한 흐름에 부합하기 위해 차세대 아키텍처로의 전환과 최적화, 그리고 새로운 AWS 서비스를 활용하여 최적의 데이터 흐름을 구축하기 위해 노력하고 있습니다. 그 결과로, Main Database 인 Aurora PostgreSQL의 사용량이 개선 되었고, 그로 인해 사양을 낮출 수 있게 되었습니다.

New Generation Architecture

AWS DatabaseAnalytics 서비스에는 Amazon RDS, Amazon DocumentDB, Amazon Neptune, Amazon ElastiCache, Amazon Athena, Amazon Managed Streaming for Apache Kafka(MSK) 등 다양한 서비들이 존재 합니다. 따라서, SpoonRadio는 아래와 같은 목표를 수립 하였습니다.

AWS Database와 Analytics 서비스들을 적재적소에 사용함에 따라 데이터를 사용하는 패턴을 변경하여 데이터 분산을 이뤄 내기 위해 새로운 아키텍처를 수립할 때 해당 내용을 고려한다.

위 내용을 기반으로 저희 SpoonRadio 아키텍처 팀은 Event Driven Architecture(EDA)를 이용하여 설계를 시작하였고, EDA는 Amazon Managed Streaming for Apache Kafka(MSK)를 이용하여 신규 서비스를 만들거나, 리펙토링이 필요한 서비스에 대해 EDA를 적용하기 시작하였습니다.

또한, 기존의 Monolithic Architecture를 MicroService Architecutre(MSA) 구조로 변환 하면서 각각의 서버들에 EDA를 적용 하였습니다.

이러한 설계를 통해 Event Driven과 Amazon MSK, 그리고 Debezium 등을 활용하는 차세대 아키텍처가 완성 되었습니다. 그로 인해 DB에서 Select하는 데이터 양이 감소 되었습니다.

Database Tuning

위에서 말했듯, AWS에는 많은 종류의 Database와 Analytics 서비스들을 보유 하고 있습니다. 각 AWS 서비스들의 관계는 연동 및 Migration이 매우 쉽게 설계되어 있고, 개발 생산성이 뛰어나 백엔드 개발자 분들의 노력과 AWS의 도움으로 적재적소에 Amazon ElastiCache for Redis와 같은 서비스를 활용함으로 DB에 접근하던 많은 쿼리를 더 빠르고 안정적으로 서비스를 설계할 수 있었습니다.

이러한 노력으로, DB의 Read / Write 가 많이 줄어듦으로 인해 DB의 Spec을 낮춰 비용을 절감할 수 있도록 준비할 수 있었습니다.

Part 2. 그럼 우리는 어떻게 Spec Down을 할 수 있을까?

Spec Down은 어떻게든 순단이 동반되어야 합니다. 그로 인해 가장 순단이 적고, 서비스에 영향이 없는 상황을 만들어 Spec Down을 고려해야 했습니다. (단순히 비용을 낮추는 것이 아닌, 비용 최적화가 목적이 되어야 합니다.)

이러한 상황을 고려하여, 이전에 무중단으로 버전 업그레이드를 하였던 PgBouncerAmazon RDS Proxy 중 고민을 하였습니다.

다시 한번 PgBouncer를 써볼까?

2022년도에 Aurora PostgreSQL의 Major Version EOL에 따라 버전 업그레이드를 수행하였습니다. 그때 “어떻게 하면 가장 짧은 중단 시간을 갖고 작업을 할 수 있을까.” 라는 고민을 통해 PgBouncer를 사용할 수 있게 되었습니다.

PgBouncer를 통해 Pool의 Resume / Pause 기능을 이용하여 최소한의 다운타임을 갖고 작업할 수 있었습니다.

다만, 버전 업그레이드는 Cluster 단위로 작동하고, Spec Down은 Instance 단위로 진행되기 때문에 버전 업그레이드 시 고려하였지만, Multiple Cluster가 지원되지 않아 포기했던 RDS Proxy를 한 번 더 고민하게 되었습니다.

Amazon RDS Proxy는 어떤 역할을 할까?

먼저 RDS Proxy는 AWS에서 제공하는 서비스로, 필요한 리소스는 아래와 같습니다.

SpoonRadio에서 RDS Proxy 없이 기존에 DB 에 접근 하는 것을 간단하게 도식화 해보면 아래와 같습니다.

그림2. SpoonRadio Database 접근 Flowchart

위에서 볼 수 있듯 Secrets Manager에 등록되어 있는 DB 정보를 Config 서버에 요청하게 되고, 인가된 권한을 갖고 있는 Amazon EC2에 DB 정보를 전달한 후, Host 정보를 Amazon Route 53의 DNS를 전달 하도록 되어있습니다.

이러한 과정을 통해 서버 내부에 DB 정보를 주입하지 않아도 DB에 접근할 수 있도록 하였습니다. 위 과정이 RDS Proxy를 사용하게 되면 어떻게 변경해야 하는지 고민하였습니다.

고민의 내용을 도식화 해보면 아래와 같습니다.

그림3. Amazon RDS Proxy를 사용하여 Database 접근을 도식화 한 Flowchart

위처럼 기존의 Config 서버를 경유하여 DB의 정보를 통해 RDS Proxy에 접속하고 RDS Proxy의 Connection pool을 이용하여 DB에 접근하는 형태로 구성을 하였습니다.

Amazon RDS Proxy를 사용해볼까?

Cluster 단위 작업을 수행해야 하는 상황이 아니었고, 작업으로 인한 Down Time도 Failover의 시간만 문제 되는 경우로 판단하여 AWS Network Load Balancer (NLB), EC2, PgBouncer 등의 설정과 종료(Terminate)까지 고려해야 하는 PgBouncer를 사용하기보다는, AWS 관리형 서비스인 RDS Proxy를 사용하기로 의사결정이 되었습니다.

Part 3. 그럼 구성을 해보자!

구성을 하기전에 어떤 문제점이 있을까?

  • 대기 Client가 많은 경우 RDS Proxy에서 거부하는 현상
  • RDS Proxy 신규 인스턴스 생성 시 LB에 편입되지 않아 Packet이 분산되지 않는 문제

AWS 솔루션즈 아키텍트와 테크니컬 어카운트 매니저분들의 도움을 받아 위 문제를 인식하고, 문제가 발생하지 않도록 준비하였습니다.

대기 Client가 많은 경우 RDS Proxy에서 거부 하는 현상

대기 Client가 많은 경우 RDS Proxy에서 거부하는 현상에 대해서는 max_connection이 Instance Size에 따라 계산되는 것을 고정값으로 변경하고, RDS Proxy에서 Connection Pool의 갯수를 max_connection의 50%만 사용하도록 수정 하였습니다.

또한, 애플리케이션에서 Connection Pool을 사용하는 것을 작업 동안 Disable 하여 Pool과 Pool이 만나 Connection을 곱집합으로 생성되는 것을 방지 하였습니다.

RDS Proxy 구성 후, 신규 instance를 생성하면 RDS Proxy의 Load Balance에 신규 instance가 편입 되지 않아서 Packet이 새로운 instance 에 들어오지 않는 문제가 있었습니다.

저희는 계속적으로 RDS Proxy를 운영하는 것이 아닌 메인터넌스에만 사용하기 때문에 신규 인스턴스를 미리 생성한 후 RDS Proxy를 생성 하는 것으로 해당 문제를 해소할 수 있었습니다.

영향도 파악을 위한 Test 구성

구성하는 순서를 아래와 같이 순서대로 정리하였습니다.

현재 상태

그림4. Amazon Route 53을 이용한 Database 구성

SpoonRadio는 위 그림처럼 DB가 구성되어 있고, 애플리케이션은 Cluster Endpoint가 아닌 Route 53의 Internal Domain을 바라보도록 구성되어 있습니다.

이러한 상황에서 RDS Proxy를 구성 하였습니다.

Instance 추가 및 RDS Proxy 추가

그림5. Amazon RDS Proxy 구성

위 그림 5에서 오른쪽 하단 빨간색 박스로 표시한 Instance는 차후 Write로 사용될 Instance로 생성 되었습니다. 따라서 아래의 설정을 추가 하였습니다.

  • Failover Priority를 설정하여 Failover시 해당 Instance가 우선시 되게 설정
  • 목표한 Spec으로 미리 생성하여 Failover되면 Write는 Spec Down이 마무리 되도록 설정

또한, 애플리케이션 입장에서 Failover된 Write Instance를 빠르게 찾기 위해 Route 53의 TTL을 10초(기본 값 : 300초)로 설정 하였습니다.

애플리케이션이 인지하는 Aurora의 Failover는 Route 53 TTL + Aurora Cluster DNS Cache 5초로 결정됩니다.

RDS Proxy 운영

그림6. Amazon RDS Proxy Connection

Spec Down을 위해 RDS Proxy를 4일간 운영한 결과 Connection은 RDS Proxy로 인해 증가하였지만 RDS의 CPU / Memory 사용률은 감소 하였고 Connection, Query Duration, Max Latency는 증가하는 현상이 나타났습니다.

또한, 기본적으로 Connection Pool을 사용하는 애플리케이션에 대해서 Connection Pool을 Disable 하도록 하여 배포 함으로 기본 준비가 완료 되었습니다.

애플리케이션의 Latency가 약 20% 증가하는 문제가 발생하긴 하였지만, 허용 가능한 범위의 증가로 서비스에 큰 문제가 없는 것을 확인하고 Spec Down을 목표로 한 날짜까지 운영하게 되었습니다.

Failover

그림7. Amazon Aurora Failover

위에서 설명한 것처럼 애플리케이션에서 빠르게 인지 하기 위해 Route 53의 TTL을 변경 하였고, 목표 스펙과 Priority를 조절한 Instance를 생성 하였기 때문에 사용량이 가장 적은 시간에 Failover를 수행 하였습니다.

그림 8. 애플리케이션 504 에러

Aurora PostgreSQL 의 경우, Failover 시 모든 Instance 가 재시작 되기 때문에 위와 같이 일시적으로 DB 에 접근이 불가능합니다. (Aurora MySQL 의 경우 해당 Instance만 재부팅 되지만, Aurora PostgreSQL의 경우 Reader Instance가 많아도 전부 재부팅됩니다.) 다행히 장애가 발생할 정도의 시간은 아니었고, 바로 정상화되었습니다.

Failover 후, Reader Instance에 대해 Spec Down을 수행하여 작업이 완료되었습니다.

Part 4. 전부 정상화되었다면, RDS Proxy를 제거하자!

RDS Proxy를 제거 하기 위해서는 기존에 RDS Proxy를 바라보고 있는 Route 53부터 원래대로 설정을 복구하고, Connection이 전부 사라진 것을 확인한 후 RDS Proxy를 제거 해야 했습니다.

Amazon Route 53의 Endpoint를 변경하자

위 그림처럼 Route 53은 더 이상 RDS Proxy를 바라보지 않고, Write는 Cluter Endpoint로 대체하고, Reader는 남아야 되는 Instance의 Endpoint를 Route 53에 입력하여, 제거 예정인 Instance에 더 이상 Connection이 맺어지지 않도록 제거 합니다.

그림 10. Amazon Route 53 Instance Endpoint에서 Cluster Endpoint 변경

Reader Instance를 제거하고, Cluster Endpoint로 Route 53에 설정하는 것으로, 모든 작업이 마무리 됩니다.

마치며

클라우드 환경에서 비용 최적화 활동은 DBA 또한 주요한 업무입니다. 특히, DBA 입장에서 서비스에 영향 없이 DB Right Sizing 진행은 도전적 과제입니다.
3년 전 스푼라디오에서 사용하고 있던 Aurora PostgreSQL는 12xlarge의 큰 사이즈를 사용하고 있었지만, 차세대 아키텍처와 꾸준한 최적화, 그리고 스푼 개발 그룹 모두의 노력으로 지금의 사이즈까지 최적화하여 안정적으로 운영하고 있습니다.

AWS 관리형 서비스인 RDS Proxy를 사용하여 무중단으로 DB Spec Down을 경험해 보면서 여러 문제점과 어려운 점이 있었지만, AWS 관계자분들의 도움으로 주요 2개 국가에 작업을 무사히 마칠 수 있었습니다.

저희의 경험과 테스트를 통해 조금이나마 작업에 도움이 되었으면 좋겠다는 마음으로, 글을 마무리하겠습니다.

감사합니다.

이름

Ryan Kim

SpoonRadio 에서 SRE팀에 소속 되어 DBA 업무를 수행 하고 있는 김광호 입니다. 저의 업무는 AWS내에서 RDS 및 Aurora 를 구축 , 운영 및 튜닝을 하고 있습니다. 많은 양의 데이터가 오류 없이 사용자에게 전달 되기 위해 노력 하고 있으며, 그로인해 많은 사용자들이 SpoonRadio 안에서 즐거운 경험을 하셨으면 좋겠습니다.

이름

Beaver Lee

SpoonRadio SRE팀에 소속 되어 DBA 업무를 수행 하고 있는 이선영 입니다. SpoonRadio를 사용하는 DJ와 청취자들에게 좋은 경험을 제공하기 위해 AWS 기반의 PostgreSQL, MySQL 등 데이터베이스를 운영 및 관리하고 있습니다.

Hoseok Seo

Hoseok Seo

서호석 솔루션즈 아키텍트는 DevOps 엔지니어로 커리어를 시작하여 다양한 분야의 프로젝트에서 개발과 운영 업무 역할을 하였고, WAS 엔지니어로 많은 고객사들의 프로젝트 지원과 장애 대응을 하였습니다. 현재는 아마존 웹서비스에서 고객분들이 AWS 클라우드와 컨테이너를 잘 활용할 수 있도록 기술적인 도움을 드리는 역할을 하고 있습니다.