콘텐츠로 이동

RDS Basics

분류: Layer 3 - AWS 인프라 & 보안

RDS(Relational Database Service)는 AWS가 MySQL, PostgreSQL, MariaDB, Oracle, SQL Server, Db2 같은 관계형 데이터베이스 엔진의 프로비저닝, 백업, 패치, 장애 감지, failover 일부를 관리해 주는 관리형 관계형 데이터베이스 서비스다.

관계형 데이터베이스는 테이블, 행, 열, SQL, 트랜잭션을 중심으로 데이터를 다룬다. RDS는 이 데이터 모델을 새로 만드는 서비스가 아니라, 기존 DB 엔진을 AWS 인프라 위에서 더 쉽게 운영하게 해 주는 관리 계층이다. 그래서 RDS를 이해할 때의 핵심 질문은 “SQL을 어떻게 쓰는가”가 아니라 DB 운영 책임 중 어디까지 AWS가 가져가고, 어디부터 애플리케이션 팀이 여전히 책임지는가다.

처음 읽을 때 붙잡을 문장은 이것이다.

RDS = 관계형 DB 엔진 + AWS가 맡는 운영 자동화 + 팀이 여전히 해야 하는 데이터/쿼리/연결 설계

2. 선행 기술의 한계 — EC2 자가 관리 DB에서 RDS로

섹션 제목: “2. 선행 기술의 한계 — EC2 자가 관리 DB에서 RDS로”

RDS가 없다고 DB를 못 쓰는 것은 아니다. EC2에 PostgreSQL이나 MySQL을 직접 설치하고, EBS 볼륨을 붙이고, cron으로 백업을 돌리고, 장애 시 standby를 승격시키면 된다. 작은 실험 환경에서는 이 방식이 더 싸고 자유로워 보일 수 있다.

문제는 서비스가 운영 단계로 들어갈 때 생긴다. DB는 애플리케이션 서버보다 상태(state)가 강하다. 서버 한 대가 죽으면 새로 띄우면 되지만, DB의 데이터 파일, 트랜잭션 로그, 백업, 복구 가능 시점, replication 상태가 깨지면 “다시 띄우기”만으로는 복구되지 않는다.

EC2 자가 관리에서 팀이 직접 해야 하는 일RDS가 기본으로 줄여 주는 운영 부담
OS와 DB 엔진 설치, 마이너 패치, 보안 패치유지보수 윈도우와 자동 마이너 업그레이드 옵션
백업 스크립트 작성, 백업 성공 여부 확인자동 백업, 트랜잭션 로그 보관, PITR(Point-in-Time Recovery)
장애 감지, standby 승격, 접속 주소 전환Multi-AZ failover와 RDS endpoint(DNS 이름) 전환
디스크 용량, 연결 수, CPU, I/O 모니터링CloudWatch 지표, Database Insights 계열 관측
standby 복제 구성, 복구 리허설, runbook 유지관리형 복제와 콘솔/API 기반 복구 흐름

이 표가 말하는 것은 “RDS를 쓰면 DB 운영을 몰라도 된다”가 아니다. RDS는 설치와 인프라 운영의 많은 부분을 자동화하지만, 잘못된 인덱스, 무제한 connection pool, Public Subnet에 둔 DB, 오래된 Read Replica를 읽는 버그, 잘못된 migration은 대신 해결해 주지 않는다.

RDS를 쓰는 경우와 EC2 자가 관리가 남는 경우

RDS가 기본값인 경우

일반적인 웹 서비스, 백오피스, 결제·주문·사용자 데이터처럼 관계형 모델과 운영 자동화가 모두 필요한 워크로드다.

백업, 패치, failover, 모니터링을 표준화하고 DB 운영 리스크를 줄이는 것이 우선일 때

자가 관리가 필요한 경우

OS 파일시스템 접근, 커널 수준 튜닝, AWS 미지원 엔진/버전, RDS가 허용하지 않는 특수 권한이나 확장이 꼭 필요한 워크로드다.

관리형 제약을 받아들이면 제품 요구사항 자체를 만족할 수 없을 때

RDS의 lineage는 “DB를 더 쉽게 만드는 콘솔”이 아니라 상태ful 시스템의 반복 운영 작업을 서비스 경계 안으로 끌어들인 것이다. 이후 절의 Multi-AZ, backup, parameter group, RDS Proxy는 모두 이 책임 경계를 구체화한다.

RDS 문서는 약어가 많다. 처음에는 모든 세부 옵션을 외우지 말고 아래 용어가 어떤 문제를 가리키는지부터 잡는다.

용어첫 정의처음 잡아야 할 경계
RDSRelational Database Service. AWS 관리형 관계형 DB 서비스다.SQL 데이터 모델 자체가 아니라 DB 운영 자동화 계층이다.
AZAvailability Zone. 한 리전 안에서 전원·네트워크·건물 장애를 분리한 장애 도메인이다.AZ가 다르면 장애 격리성은 높아지지만, 네트워크 지연과 비용이 0이 되는 것은 아니다.
DB instanceRDS에서 실행되는 DB 서버 단위다. CPU, 메모리, 스토리지, 엔진 버전을 가진다.EC2처럼 보이지만 OS 접속과 파일시스템 직접 제어는 제한된다.
Endpoint애플리케이션이 접속하는 DNS 이름이다. 예: mydb.xxxx.ap-northeast-2.rds.amazonaws.com.failover 때 코드의 주소는 그대로지만 DNS가 새 primary를 가리키도록 바뀐다.
Multi-AZ여러 AZ에 DB를 두고 자동 failover를 제공하는 고가용성(High Availability, HA) 배포 계열이다.DB instance와 DB cluster는 복제 방식, 인스턴스 수, 읽기 가능 여부가 다르다.
Multi-AZ DB instanceprimary 1개와 다른 AZ의 동기식 standby 1개를 두는 배포다.standby는 failover 전 읽기 트래픽을 받지 않는다.
Multi-AZ DB clusterwriter 1개와 서로 다른 AZ의 readable reader 2개를 두는 준동기식 배포다.MySQL/PostgreSQL용이며 reader endpoint와 replica lag를 함께 운영한다.
Read Replicaprimary의 변경을 비동기로 따라가는 읽기 복제본이다.읽기 부하 분산용이며, stale read(오래된 값 읽기)를 허용해야 한다.
ReplicaLagRead Replica나 Multi-AZ DB cluster reader가 writer보다 뒤처진 정도를 나타내는 CloudWatch 지표다.0이 아니면 최신 데이터가 아닐 수 있다. 값이 없거나 음수면 엔진별 metric과 복제 상태를 확인한다.
PITRPoint-in-Time Recovery. 자동 백업과 로그를 이용해 특정 시점의 새 DB로 복원하는 기능이다.기존 DB를 시간여행시키는 것이 아니라 보통 새 인스턴스로 복원해 전환한다.
Snapshot특정 시점의 수동 백업 이미지다.자동 보관 기간과 별개로 보관되며, 삭제 전까지 비용과 관리 책임이 남는다.
Parameter GroupDB 설정값 묶음이다. max_connections, logging, timeout 같은 엔진 파라미터를 RDS에 적용한다.동적 파라미터와 재시작이 필요한 정적 파라미터를 구분해야 한다.
Connection Pool애플리케이션이 DB 연결을 미리 열어 재사용하는 구조다.pool을 키우면 빠른 것이 아니라 DB의 동시 연결 한도를 소비한다.
RDS Proxy애플리케이션과 RDS 사이에서 DB 연결을 관리하고 failover 영향을 줄이는 관리형 프록시다.모든 쿼리를 빠르게 만드는 캐시가 아니다. 연결 수와 failover 회복을 다루는 계층이다.
PinningRDS Proxy가 세션 상태 때문에 한 클라이언트 연결을 특정 DB 연결에 고정하는 현상이다.pinning이 많으면 multiplexing 효과가 줄어든다.
Database InsightsCloudWatch에서 DB load, wait event, Top SQL 같은 성능 신호를 보는 관측 기능이다.제품명보다 “DB가 CPU, I/O, lock 중 어디서 기다리는가”를 읽는 사고가 중요하다.

4. 관리 책임 경계 — AWS가 맡는 것과 팀이 남겨 두면 안 되는 것

섹션 제목: “4. 관리 책임 경계 — AWS가 맡는 것과 팀이 남겨 두면 안 되는 것”

RDS를 처음 쓰면 “관리형”이라는 단어 때문에 모든 장애가 AWS 책임처럼 느껴질 수 있다. 실제로는 책임이 나뉜다.

영역RDS가 해 주는 것애플리케이션 팀이 여전히 해야 하는 것
설치/패치엔진 설치, 관리형 패치, 유지보수 윈도우패치 시점 선택, major version upgrade 테스트, 호환성 검증
백업/복구자동 백업, 트랜잭션 로그 보관, snapshot 생성과 복원 API보관 기간 설정, 복구 리허설, 어느 시점으로 되돌릴지 판단
고가용성배포 모드별 standby/reader, 장애 감지, writer 승격, endpoint 전환재연결 로직, DNS TTL, idempotent retry, failover 중 사용자 영향 설계
보안저장 시 암호화 옵션, IAM 통합, VPC 배치, SG 적용Private Subnet 배치, SG-as-source 규칙, 비밀번호/secret 관리, 권한 최소화
성능인스턴스 클래스, 스토리지 옵션, 지표 제공쿼리 설계, 인덱스, connection pool 크기, slow query 분석
비용사용량 기반 과금과 비용 지표 제공Multi-AZ, storage autoscaling, snapshot, idle 개발 DB 비용 관리

짧은 반례를 보자. RDS 자동 백업이 켜져 있어도 애플리케이션이 잘못된 migration으로 users.email을 전부 NULL로 덮어쓰면, RDS는 그것을 정상 쓰기로 기록한다. 복구하려면 PITR로 사고 직전의 새 DB를 만들고, 어떤 데이터를 되살릴지 비교·전환해야 한다. 관리형 백업은 복구 수단이지, 잘못된 쓰기를 자동으로 판별하는 보호막이 아니다.

또 다른 반례는 연결 수다. RDS가 max_connections를 제공해도 ECS Task가 늘어날 때 pool 크기를 같이 계산하지 않으면 too many connections가 난다. RDS가 인스턴스를 운영해 주는 것과 애플리케이션이 연결을 절제하는 것은 다른 책임이다.

책임 경계 worked example — minor version upgrade

섹션 제목: “책임 경계 worked example — minor version upgrade”

RDS는 마이너 버전 패치를 유지보수 윈도우에 적용할 수 있다. 이것은 “패치 파일을 다운로드하고 설치하는 작업”을 AWS가 해 준다는 뜻이다. 하지만 다음 질문은 여전히 팀의 일이다.

현재: RDS for MySQL 8.0.x
목표: 새 마이너 버전 적용
AWS가 해 주는 것:
- 지원되는 새 마이너 버전 제공
- 유지보수 윈도우에 패치 실행
- Multi-AZ 구성이라면 DB instance standby 또는 DB cluster reader의 작업과 failover 흐름 관리
팀이 해야 하는 것:
- 새 버전에서 ORM, migration, SQL mode, collation, extension 호환성 확인
- staging snapshot restore 후 smoke test
- 배포 시간대와 rollback 판단 기준 준비
- failover 중 재시도와 사용자 영향 확인

이 예시는 RDS의 “관리형”을 과소평가하지도, 과대평가하지도 않게 만든다. AWS는 반복 운영 작업을 자동화하지만, 데이터 모델과 애플리케이션 호환성은 서비스 팀의 지식 없이는 판단할 수 없다.

5. Multi-AZ - 두 배포 모드와 DNS failover

섹션 제목: “5. Multi-AZ - 두 배포 모드와 DNS failover”

Multi-AZ는 RDS 가용성의 핵심 구성이다. 그러나 이름 하나 아래에 Multi-AZ DB instance deploymentMulti-AZ DB cluster deployment라는 서로 다른 방식이 있다. 둘 다 AZ나 writer 장애 시 자동 failover를 제공하지만, “Multi-AZ는 동기 standby 하나”라고만 외우면 cluster의 준동기 복제와 readable reader를 놓친다.

배포 모드토폴로지commit 복제 경계장애 전 읽기핵심 목적
Multi-AZ DB instanceprimary 1 + 다른 AZ의 standby 1standby로 동기 복제standby 읽기 불가단일 DB instance의 고가용성
Multi-AZ DB cluster3개 AZ의 writer 1 + reader 2reader 중 최소 1개의 확인을 요구하는 준동기 복제reader endpoint로 두 replica 읽기 가능고가용성 + 읽기 용량 + 더 낮은 write latency

5.1 Multi-AZ DB instance - 동기식 비가독 standby

섹션 제목: “5.1 Multi-AZ DB instance - 동기식 비가독 standby”
Multi-AZ DB instance failover의 핵심 흐름
flowchart TD
App["Application"] --> Endpoint["RDS Endpoint DNS"]
Endpoint --> Primary["Primary DB in AZ-A"]
Primary --> Sync["동기 복제"]
Sync --> Standby["Standby DB in AZ-B"]
Primary --> Detect{"Primary 장애 감지"}
Detect --> Promote["Standby를 새 Primary로 승격"]
Promote --> DNS["Endpoint DNS가 새 Primary IP를 가리킴"]
DNS --> Reconnect["Application은 같은 endpoint로 재연결"]

이 배포에서 중요한 단어는 동기 복제다. primary의 변경은 다른 AZ의 standby로 동기 복제된다. standby는 장애 전 일반 읽기 endpoint로 노출되지 않으며, failover 때 승격되는 고가용성 자원이다. 이 덕분에 장애 시 데이터 유실 가능성을 낮추지만, Single-AZ보다 write/commit 지연과 비용이 늘 수 있다.

5.2 Multi-AZ DB cluster - 준동기식 readable replica 두 개

섹션 제목: “5.2 Multi-AZ DB cluster - 준동기식 readable replica 두 개”

Multi-AZ DB cluster는 MySQL과 PostgreSQL에서 writer 1개와 reader 2개를 서로 다른 3개 AZ에 둔다. writer가 변경을 두 reader에 보내고, 최소 한 reader의 확인을 받아야 commit할 수 있는 semisynchronous replication(준동기 복제)을 사용한다. 이 확인은 두 reader 모두에서 변경이 완전히 실행·commit됐다는 뜻은 아니다.

두 reader는 자동 failover 대상이면서 read traffic도 처리한다. 애플리케이션은 writer endpoint로 쓰고 reader endpoint로 읽을 수 있다. 따라서 일반 Multi-AZ DB instance의 숨은 standby와 달리 읽기 용량을 제공하지만, engine 기반 복제라 ReplicaLag가 생길 수 있다. failover 후보를 고를 때도 최신 change record와 lag가 중요하므로, “준동기 commit이면 모든 reader가 항상 최신”이라고 가정하면 안 된다.

failover 시간은 “완전 무중단”이 아니다

섹션 제목: “failover 시간은 “완전 무중단”이 아니다”

AWS 공식 문서 기준으로 일반적인 Multi-AZ DB instance failover는 보통 60~120초가 걸린다. 큰 트랜잭션이 진행 중이었거나 recovery가 길면 더 오래 걸릴 수 있다. Multi-AZ DB cluster, 즉 writer 1개와 readable reader 2개를 두는 구성은 보통 35초 미만 failover를 목표로 한다. cluster는 reader lag를 해소한 뒤 새 writer를 승격해야 하므로 실제 시간은 lag와 engine 상태에 따라 달라질 수 있다.

이 숫자는 “RDS가 primary를 바꾸는 시간”에 가깝다. 사용자가 체감하는 시간은 여기에 애플리케이션의 DNS 캐시, connection pool의 stale socket, 드라이버 재시도 정책이 더해진다.

체감 장애 시간
= RDS 장애 감지와 standby/reader 승격
+ DNS 전파와 런타임 DNS cache 만료
+ connection pool이 옛 연결을 버리고 새 연결을 만드는 시간
+ 애플리케이션 retry/backoff 시간

Multi-AZ에서 endpoint 이름은 그대로지만 그 이름이 가리키는 IP는 바뀔 수 있다. 이때 런타임이 DNS 결과를 너무 오래 캐시하면 RDS failover는 끝났는데 애플리케이션만 옛 primary IP로 계속 접속한다.

Java의 JVM DNS cache TTL(Time To Live)은 특히 확인해야 한다. AWS Java SDK 문서는 failover 대응을 위해 JVM DNS TTL을 60초 미만 또는 60초 수준으로 두는 구성을 안내한다. networkaddress.cache.ttl이 무한 캐시처럼 동작하면 failover 뒤에도 옛 IP를 계속 쓸 수 있다.

Node.js 자체의 dns.lookup은 일반적으로 JVM처럼 영구 DNS 캐시를 두지 않지만, DB driver나 ORM의 connection pool은 옛 TCP 연결을 붙잡을 수 있다. 그래서 Multi-AZ를 켰다면 endpoint 이름만 믿지 말고 pool idle timeout, connection lifetime, retry 정책을 같이 본다.

실패 신호의미먼저 볼 개념
RDS 이벤트에는 failover 완료, 앱은 계속 ECONNREFUSEDDNS cache나 pool이 옛 primary IP/소켓을 붙잡고 있다DNS TTL, connection pool 재연결
failover 중 일부 요청만 오래 실패프로세스별 cache와 pool 상태가 서로 다르다런타임 DNS cache, pool instance 분산
재시작하면 즉시 회복코드보다 프로세스 안의 stale DNS/socket 가능성이 높다TTL, idle timeout, RDS Proxy

Multi-AZ는 공짜 안전장치가 아니다. DB instance deployment는 standby가 추가되어 DB instance-hour 비용이 대체로 한 대 더 붙고, DB cluster deployment는 writer와 reader 두 개, 총 3개 DB instance를 과금한다. 전체 청구액이 단순히 2배 또는 3배라는 뜻은 아니다. 스토리지, I/O, 백업, 데이터 전송, RDS Proxy 같은 항목은 구성별로 따로 계산해야 한다.

개발/스테이징 DB에서 Multi-AZ를 끄는 팀이 많은 이유가 여기에 있다. 프로덕션에서는 “한 달에 추가로 내는 비용”과 “DB 장애 1시간이 만드는 매출 손실, SLA 위반, 엔지니어 야간 대응 비용”을 비교한다.

작은 숫자 감각을 붙이면 결정이 더 선명하다. 월 30일 기준 99.9% 가용성은 한 달에 약 43분 다운타임을 허용하고, 99.95%는 약 22분, 99.99%는 약 4분 수준만 허용한다. DB 수동 복구가 30분 이상 걸릴 가능성이 있고 그 시간의 손실이 Multi-AZ 추가 비용보다 크다면, Multi-AZ는 “비싼 옵션”이 아니라 복구 시간을 사는 선택이 된다.

퀴즈

Multi-AZ를 켜면 읽기 부하도 자동으로 분산될까?

힌트: standby의 목적과 endpoint 노출 여부를 떠올린다.

정답 보기

일반적인 Multi-AZ DB instance의 동기식 standby는 failover용이라 읽을 수 없다. 반면 Multi-AZ DB cluster는 준동기식 reader 두 개를 읽기와 failover에 함께 사용한다. 별도 비동기 Read Replica도 읽기 확장 선택지다.

6. Read Replica — 읽기 확장과 ReplicaLag

섹션 제목: “6. Read Replica — 읽기 확장과 ReplicaLag”

Read Replica는 primary의 변경을 비동기로 따라가는 별도 DB다. 쓰기는 primary로 보내고, stale read를 허용할 수 있는 조회를 replica로 보낸다. “비동기”라는 말은 primary commit이 먼저 끝나고, 변경이 replica에 나중에 도착할 수 있다는 뜻이다.

쓰기 요청:
Application -> Primary -> commit 성공
-> 나중에 Replica로 변경 전파
읽기 요청:
최신성이 중요한 조회 -> Primary
오래된 값을 잠깐 봐도 되는 조회 -> Read Replica

아래 비교의 Multi-AZDB instance deployment를 뜻한다. Multi-AZ DB cluster의 reader는 고가용성과 읽기 용량을 함께 제공하므로 이 표의 “standby 읽기 불가”를 그대로 적용하면 안 된다.

항목Multi-AZ DB instanceRead Replica
주목적장애 대비, 자동 failover읽기 부하 분산, 리포트/검색성 조회 분리
복제 방식동기식 standby 복제비동기 복제
endpoint일반 단일 standby 구성은 같은 writer endpoint 사용replica별 endpoint가 따로 있다
읽기 사용standby는 보통 직접 읽지 않는다애플리케이션이 읽기 쿼리를 replica endpoint로 보낸다
실패 모드failover 중 연결 끊김과 재연결stale read, ReplicaLag 증가

상품 재고가 10개에서 9개로 줄었다고 가정하자.

T0: Primary에 UPDATE inventory SET stock = 9 WHERE sku = 'A' commit
T1: 사용자가 주문 완료 화면으로 이동
T2: 화면 조회가 Read Replica로 라우팅
T3: ReplicaLag = 5초라 replica에는 아직 stock = 10

이 상황은 DB 장애가 아니다. Read Replica가 약속한 모델 안에서 오래된 값을 읽은 것이다. 재고, 잔액, 결제 상태, 권한 변경처럼 최신성이 중요한 조회는 primary로 보내야 한다. 반대로 대시보드 집계, 검색 자동완성, 오래된 리포트처럼 몇 초 지연이 괜찮은 조회는 replica 후보가 된다.

ReplicaLag는 이 판단을 관측 가능한 숫자로 바꿔 준다.

ReplicaLag 값읽는 방법판단
0replica가 primary와 거의 동기화된 상태일반 읽기 분산에 적합
5replica가 primary보다 약 5초 뒤처진 상태최신성 민감 조회는 primary로 보낸다
-1 또는 없음복제 상태가 비정상·미측정·미지원일 수 있음replica 상태와 엔진별 metric 정의 확인

TypeORM 같은 ORM의 replication 옵션은 설정에 따라 SELECT를 replica로 라우팅할 수 있다. 이 기능을 쓰더라도 “모든 SELECT는 replica”가 기본값이 되면 안 된다. 최신성이 필요한 읽기는 명시적으로 primary를 쓰는 escape hatch가 있어야 한다.

// 최신성 민감 조회는 replica 자동 라우팅을 우회해 primary를 명시한다.
const runner = dataSource.createQueryRunner("master");
const order = await runner.manager.findOne(Order, { where: { id: orderId } });
await runner.release();

어떤 조회를 replica로 보내도 되는가

섹션 제목: “어떤 조회를 replica로 보내도 되는가”

처음에는 아래처럼 데이터의 “최신성 민감도”로 나눈다.

조회 종류Replica 후보인가이유
주문 직후 주문 상세보통 아니오사용자가 방금 만든 상태를 즉시 확인해야 한다.
재고 차감 직후 재고 수량아니오stale read가 oversell이나 잘못된 의사결정으로 이어질 수 있다.
관리자 대시보드의 5분 단위 집계몇 초 지연보다 primary 부하 분리가 더 중요할 수 있다.
검색 자동완성, 추천 후보eventual consistency를 사용자 경험이 흡수할 수 있다.
권한 변경 직후 접근 가능 여부보통 아니오이전 권한을 읽으면 보안 문제가 된다.

이 기준은 코드 구조에도 영향을 준다. repository 계층에서 “읽기니까 replica”로 자동화하기보다, 도메인별로 최신성 요구를 표시할 수 있어야 한다. replica는 성능 도구지만, 잘못 쓰면 에러 없는 정합성 버그가 된다.

7. 백업, Snapshot, PITR — 복구 가능 시점을 설계한다

섹션 제목: “7. 백업, Snapshot, PITR — 복구 가능 시점을 설계한다”

RDS 백업을 이해하려면 세 단어를 구분해야 한다.

개념의미주의할 점
자동 백업RDS가 정해진 backup window에 DB를 백업하고 로그를 보관하는 기능보관 기간은 DB instance에서 0~35일 범위로 설정한다. 0은 자동 백업 비활성화
PITR자동 백업과 트랜잭션 로그로 특정 시점의 DB를 새로 복원하는 기능최근 몇 분은 엔진과 상태에 따라 복원 가능 시점에 아직 포함되지 않을 수 있다
수동 Snapshot사용자가 특정 시점에 만든 백업 이미지자동 보관 기간과 별개로 남고, 삭제 전까지 비용과 관리 책임이 있다

PITR(Point-in-Time Recovery)은 “사고 전 10분으로 기존 DB를 되감기”가 아니다. 보통은 사고 전 시점의 새 DB instance를 만들고, 애플리케이션이 어느 DB를 바라볼지 전환하거나 필요한 데이터만 비교해 되살린다.

작은 사고 시나리오를 따라가 보자.

10:00 정상 상태
10:20 잘못된 배포가 users 테이블 일부를 덮어씀
10:30 장애 인지
10:35 10:19 시점으로 PITR 복원 시작
11:10 복원된 새 DB에서 정상 데이터 확인
11:30 필요한 데이터만 추출하거나 애플리케이션 endpoint 전환

여기서 중요한 결정은 “복원 버튼을 누를 수 있는가”가 아니라 “어느 시점이 안전한가”, “복원된 DB를 어떻게 검증할 것인가”, “현재 DB에 들어온 정상 쓰기와 어떻게 합칠 것인가”다. 자동 백업은 도구이고, 복구 전략은 팀의 책임이다.

반례도 있다. 자동 백업 보관 기간을 1일로 두면 비용은 줄지만, 3일 전에 들어간 데이터 오염을 PITR로 되돌릴 수 없다. 반대로 모든 스냅샷을 영구 보관하면 복구 선택지는 늘지만 비용과 개인정보 보관 리스크가 커진다.

복구를 공부할 때는 RPO와 RTO를 같이 둔다.

용어RDS에서 묻는 질문
RPO(Recovery Point Objective)얼마 전 데이터까지 잃어도 되는가latest restorable time이 업무 요구보다 충분히 가까운가
RTO(Recovery Time Objective)복구 완료까지 얼마나 걸려도 되는가PITR DB 생성, 검증, endpoint 전환까지 몇 분/몇 시간이 걸리는가

예를 들어 “최대 5분 데이터 손실, 30분 안 복구”가 요구사항이라면 자동 백업 보관만 켜 둔 것으로는 부족하다. 복원된 DB에서 핵심 테이블 수, migration version, 애플리케이션 smoke test를 확인하는 절차가 30분 안에 끝나는지 리허설해야 한다. 반대로 내부 리포트 DB라면 RPO 1시간, RTO 4시간도 충분할 수 있다. 백업 설정은 업무 손실 기준과 연결될 때 의미가 생긴다.

8. Parameter Group과 Connection Pool — 연결 수를 손으로 계산한다

섹션 제목: “8. Parameter Group과 Connection Pool — 연결 수를 손으로 계산한다”

Parameter Group은 RDS DB instance에 적용되는 DB 설정값 묶음이다. PostgreSQL의 shared_buffers, MySQL의 max_connections, slow query log 설정, timeout 값처럼 엔진별 파라미터가 여기에 들어간다.

파라미터에는 적용 방식 차이가 있다.

종류의미실패 신호
Dynamic parameterDB 재시작 없이 적용될 수 있는 값바꾼 직후 효과가 보이지만, 세션 단위 설정과 충돌할 수 있다
Static parameterDB 재시작 또는 failover가 필요할 수 있는 값콘솔에 pending-reboot가 보이고 값이 바로 반영되지 않는다
Default parameter groupAWS가 제공하는 기본 그룹직접 수정할 수 없거나 변경 추적이 어렵다. 운영 DB는 custom group을 붙이는 편이 낫다

Parameter Group을 잘못 읽으면 “값을 바꿨는데 왜 안 먹지?”가 된다. 이때 먼저 볼 것은 앱 코드가 아니라 해당 파라미터가 dynamic인지 static인지, 현재 DB에 붙은 group이 내가 수정한 group인지, 적용 상태가 pending-reboot인지다.

처음에는 모든 파라미터를 외우지 말고 max_connections 하나로 감각을 만든다. max_connections는 DB가 동시에 받아들일 수 있는 client connection 수다. 이 값은 엔진과 인스턴스 메모리에 따라 기본값이 계산된다. MySQL 계열 RDS의 기본식은 DBInstanceClassMemory / 12582880 형태로 설명되며, 대략 메모리 MB를 12로 나눈 감각에 가깝다. 1GiB급 작은 인스턴스라면 기본 동시 연결 수가 80~90대에 머물 수 있다는 뜻이다.

애플리케이션 쪽 계산은 더 직접적이다.

최대 DB 연결 수요 = 실행 중인 애플리케이션 프로세스 수 × 프로세스당 pool max
예:
ECS Task 10개 × pool max 10 = 최대 100개 연결
작은 RDS의 max_connections가 약 85라면 이미 초과 가능

Connection Pool(연결 풀)은 요청마다 DB 연결을 새로 만들지 않기 위해 미리 열린 연결을 재사용하는 구조다. DB 연결은 TCP handshake, TLS, 인증, 세션 초기화 비용이 있으므로 재사용이 필요하다. 하지만 pool은 성능 가속 버튼이 아니다. 프로세스가 많아질수록 pool max의 곱만큼 DB 연결을 잡아먹는다.

서비스가 아래처럼 배포되어 있다고 가정하자.

ECS Service desired count: 12 tasks
각 task의 Node.js 프로세스: 1개
TypeORM pool max: 10
RDS max_connections: 150
운영용 여유분: 30 connections

계산은 이렇게 한다.

앱 최대 연결 수요 = 12 × 10 = 120
DB 운영 여유분 포함 = 120 + 30 = 150

이 구성은 평소에는 맞아 보이지만 rolling deployment 중에는 기존 task와 신규 task가 잠깐 동시에 떠 있을 수 있다. 그 순간 task가 18개까지 늘면 18 × 10 = 180이 되어 한도를 넘는다. 그래서 pool max는 정상 상태뿐 아니라 배포 중 동시성, 배치 작업, migration, DBA 접속 여유를 함께 보고 정한다.

잘못된 직관왜 틀렸나
pool max를 키우면 항상 빨라진다DB CPU, lock, I/O가 병목이면 연결만 늘어 대기열과 context switching이 늘 수 있다
too many connections는 RDS가 작아서만 난다애플리케이션 task 수와 pool 설정이 한도를 초과한 설계 문제일 수 있다
Parameter Group에서 max만 키우면 끝이다작은 인스턴스에서 연결 수만 늘리면 메모리 압박과 성능 저하가 생길 수 있다

9. RDS Proxy — 연결 다중화와 failover 영향 축소

섹션 제목: “9. RDS Proxy — 연결 다중화와 failover 영향 축소”

RDS Proxy는 애플리케이션과 RDS 사이에 놓이는 관리형 데이터베이스 프록시다. 핵심 기능은 두 가지다.

  1. 애플리케이션의 많은 client connection을 더 적은 수의 DB connection으로 재사용한다.
  2. failover 때 proxy가 DB 상태 변화를 추적해 애플리케이션의 재연결 부담을 줄인다.
RDS Proxy 없음:
ECS Task 100개 × pool max 5 = RDS에 최대 500개 연결
RDS Proxy 사용:
ECS Task 100개 -> Proxy client connection 500개 가능
Proxy -> RDS backend connection 100개 이하로 재사용 가능

이 숫자는 개념 예시다. 실제 감소율은 쿼리 시간, 트랜잭션 길이, 세션 상태 사용, proxy 설정에 따라 달라진다. 짧고 독립적인 쿼리가 많을수록 multiplexing 효과가 좋고, 긴 트랜잭션이나 세션 상태가 많을수록 줄어든다.

AWS 블로그의 테스트에서는 Aurora MySQL failover에서 직접 연결 평균 약 24초가 RDS Proxy 경유 평균 약 3.1초로 줄었고, RDS Multi-AZ MySQL 테스트에서는 직접 연결 평균 약 36.8초가 proxy 경유 약 25.1초로 줄었다. 이 수치는 특정 드라이버와 테스트 조건의 결과다. 기억할 결론은 “RDS Proxy가 항상 3초로 만들어 준다”가 아니라 DNS 전파, 새 연결 수립, stale pool 처리 일부를 proxy 계층으로 옮겨 failover 체감 시간을 줄일 수 있다는 점이다.

Pinning은 RDS Proxy가 특정 client connection을 특정 backend DB connection에 고정하는 현상이다. 세션 상태가 다른 요청과 섞이면 안 되는 경우 proxy는 연결을 공유하지 못한다.

Pinning이 생기기 쉬운 예시는 다음과 같다.

  • 세션 변수를 설정한다. 예: SET @user_id = 1
  • 임시 테이블을 만든다. 예: CREATE TEMPORARY TABLE
  • 사용자 잠금이나 advisory lock을 오래 잡는다.
  • 멀티 statement를 한 번에 보낸다. 예: query1; query2;
  • 긴 트랜잭션에서 세션 상태를 바꾼다.

CloudWatch의 DatabaseConnectionsCurrentlySessionPinned metric은 현재 pinning된 DB connection 수를 보는 데 쓰인다. 이 값이 높으면 “RDS Proxy를 붙였는데 연결 수가 별로 줄지 않는다”는 현상이 생긴다.

퀴즈

RDS Proxy를 붙였는데 DatabaseConnections가 거의 줄지 않는다면 무엇을 먼저 의심할까?

힌트: Proxy가 연결을 공유하지 못하게 만드는 세션 상태를 떠올린다.

정답 보기

pinning을 의심한다. 세션 변수, 임시 테이블, 긴 트랜잭션, 멀티 statement 때문에 client connection이 특정 DB connection에 고정되면 multiplexing 효과가 줄어든다.

RDS Proxy는 좋은 도구지만 “RDS 앞에는 무조건 Proxy”가 아니다.

상황판단
Lambda나 짧게 뜨는 worker가 동시에 수백~수천 연결을 만든다RDS Proxy 후보가 강하다. connection storm을 흡수할 수 있다.
ECS Task가 많고 배포 때 connection spike가 반복된다pool sizing과 함께 RDS Proxy를 검토한다.
Multi-AZ failover 때 DNS/pool 회복 시간이 사용자 영향으로 커진다RDS Proxy가 회복 시간을 줄이는 데 도움이 될 수 있다.
소수의 장기 실행 서버가 안정적인 pool을 유지한다먼저 pool max, idle timeout, 쿼리 시간을 조정해도 충분할 수 있다.
세션 변수, 임시 테이블, 긴 트랜잭션이 많다pinning 때문에 효과가 작을 수 있으므로 metric으로 검증한다.

선택 기준은 “Proxy가 있으면 좋아 보인다”가 아니라 DB connection을 줄일 실제 반복 패턴이 있는가, failover 회복 시간을 줄여야 하는 요구가 있는가, pinning 때문에 효과가 사라지지 않는가다.

10. Private Subnet과 Security Group — DB는 인터넷 진입점이 아니다

섹션 제목: “10. Private Subnet과 Security Group — DB는 인터넷 진입점이 아니다”

RDS는 보통 Private 또는 DB Subnet에 둔다. Publicly accessible 옵션을 켜고 Public Subnet에 두면 인터넷에서 DB endpoint로 직접 접근 가능한 경로가 생긴다. DB는 사용자 요청의 첫 진입점이 아니라 애플리케이션 서버 뒤의 상태 저장소이므로, 기본 설계는 다음과 같다.

Internet
-> ALB in Public Subnet
-> ECS Task / EC2 in Private App Subnet
-> RDS in DB Subnet

VPC/Subnet/SG 문서에서 배운 SG-as-source 패턴이 여기서 그대로 쓰인다.

RDS Security Group inbound:
Type: PostgreSQL
Port: 5432
Source: sg-ecs-task
ECS Task Security Group outbound:
Destination: sg-rds
Port: 5432

이 패턴은 10.0.11.42/32 같은 특정 IP보다 안전하다. ECS Task나 EC2가 재배포되어 private IP가 바뀌어도 같은 SG를 달고 있으면 접근 권한이 유지된다. 반대로 같은 VPC 안에 있더라도 source SG가 허용되지 않은 리소스는 DB에 붙을 수 없다.

연결 실패를 볼 때는 “RDS가 죽었나”보다 먼저 네트워크 경로를 나눈다.

증상의미먼저 볼 곳
Connection timed out패킷이 DB까지 도달하지 못했거나 SG/NACL/route에서 막힘RDS SG inbound, ECS SG outbound, DB Subnet route
ECONNREFUSEDendpoint는 해석됐지만 대상 포트 연결이 거부되거나 전환 중failover 이벤트, pool stale socket, DB 상태
로컬에서는 되는데 ECS에서만 실패로컬 IP 허용과 ECS Task SG 허용이 다르다RDS SG source, 배포 환경의 DATABASE_URL
DNS는 해석되는데 연결만 안 됨endpoint 문자열과 network path는 별도 문제Flow Logs, Reachability Analyzer, SG

RDS 비밀번호나 접속 문자열은 애플리케이션 환경변수에 평문으로 오래 남기지 않는 편이 좋다. 실무에서는 Secrets Manager나 SSM Parameter Store를 쓰고, 이를 읽는 권한은 ECS Task Role 같은 IAM Role에 좁게 부여한다. 이 부분은 IAM과 Secrets Management 주제와 연결되지만, RDS 문서에서는 DB endpoint는 private path로, secret은 workload role로라는 원칙만 잡으면 충분하다.

11. 성능 관측 — Database Insights는 원인 분류 도구다

섹션 제목: “11. 성능 관측 — Database Insights는 원인 분류 도구다”

RDS 성능 문제를 처음 보면 CPU 그래프만 보게 된다. 하지만 DB는 CPU, I/O, lock, connection wait, buffer/cache miss, 쿼리 계획 같은 여러 이유로 느려진다. Database Insights나 Performance Insights 계열 도구를 보는 이유는 “느리다”를 **무엇을 기다리는가(wait event)**로 나누기 위해서다.

도구 이름과 콘솔 위치는 AWS가 바꿀 수 있다. 현재 문서에서 중요한 것은 제품명 변화가 아니라 아래 관측 모델이다.

관측 항목읽는 법다음 질문
DB LoadDB가 동시에 처리하거나 기다리는 작업량CPU bound인가, I/O wait인가, lock wait인가
Top SQL부하를 많이 만드는 SQL특정 쿼리가 전체 부하를 지배하는가
Wait EventDB 세션이 기다리는 원인디스크, lock, client, CPU 중 어디인가
DatabaseConnections현재 열린 DB 연결 수pool max와 task 수 계산이 맞는가
FreeStorageSpace남은 스토리지auto scaling이나 용량 계획이 필요한가
ReadIOPS/WriteIOPS스토리지 읽기/쓰기 요청량쿼리/인덱스/배치 작업이 I/O를 밀어 올리나

슬로우 쿼리의 첫 해석도 이 모델을 따른다.

API 응답이 5초 이상 걸림
-> Top SQL에서 특정 SELECT가 부하 상위
-> EXPLAIN으로 Seq Scan 또는 잘못된 join 순서 확인
-> 필요한 인덱스, 쿼리 조건, N+1 쿼리, pagination을 검토

Seq Scan이 보인다고 항상 잘못은 아니다. 작은 테이블 전체를 읽는 것이 인덱스보다 빠를 수 있다. 문제는 “Seq Scan이라는 단어”가 아니라 테이블 크기, 조건 선택도, 호출 빈도, 응답 지연이 함께 커지는 상황이다.

12. 비용 감각 — RDS 비용은 인스턴스만 보지 않는다

섹션 제목: “12. 비용 감각 — RDS 비용은 인스턴스만 보지 않는다”

RDS 비용은 DB instance class만으로 끝나지 않는다. 자주 놓치는 축은 다음과 같다.

비용 축학습용 판단 기준
Instance classCPU와 메모리 여유가 지속적으로 낮으면 downsizing 후보지만, peak와 배포 시간을 함께 본다.
Multi-AZ DB instance동기식 standby 1개의 비용이 추가된다. 프로덕션 가용성 비용으로 정당화되는지 본다.
Multi-AZ DB clusterwriter 1개와 readable reader 2개를 과금한다. HA와 읽기 용량, 더 낮은 write latency가 모두 필요한지 본다.
Read Replica읽기 부하를 줄이지만 replica instance 비용과 replica lag 운영 비용이 생긴다.
Storage할당 스토리지, IOPS, storage autoscaling 최대치를 본다.
Backup retention보관 기간이 길수록 복구 선택지는 늘지만 백업 보관 비용과 데이터 보존 리스크가 커진다.
Manual snapshot자동 보관 기간과 별개로 남는다. 오래된 snapshot은 비용과 개인정보 보관 리스크를 만든다.
RDS Proxy연결 안정성 비용이다. 모든 서비스에 기본으로 붙이기보다 연결 폭증/failover 요구를 보고 결정한다.
Dev/Staging idle DB사용하지 않는 시간에도 과금된다. 중지 가능한 DB는 중지하되, 장기 중지는 자동 재시작 제약을 확인한다.

Storage Auto Scaling은 특히 반례가 중요하다. 스토리지가 부족할 때 자동 확장은 장애를 막는 데 도움이 되지만, 한 번 늘어난 allocated storage는 일반적으로 같은 인스턴스에서 바로 줄일 수 없다. 용량을 줄이려면 더 작은 스토리지로 새 DB를 복원하거나 dump/restore 같은 별도 절차가 필요하다. 그래서 최대 스토리지 값을 너무 크게 열어 두면 “장애 예방”이 “지속 비용 증가”로 바뀔 수 있다.

비용 최적화는 한 번의 설정이 아니라 관측 주기다. 최소 1~2주 정도의 CPU, connection, I/O, storage 증가 추세를 보고, peak 시간과 batch 시간까지 포함해 판단한다. 개발 DB 자동 중지, 예약형 구매, gp3 같은 스토리지 옵션, snapshot 정리는 모두 비용 절감 후보지만, 프로덕션 복구성과 성능을 해치지 않는 범위에서만 적용한다.

정확한 금액은 리전과 시점의 AWS Pricing을 봐야 하지만, 비용 구조는 손으로 그릴 수 있어야 한다.

단일 AZ 운영 DB:
DB instance 1대
storage 200GB
automated backup 7일
Multi-AZ 전환:
DB instance 2대에 가까운 instance-hour
동기식 비가독 standby 유지
failover 안정성 증가
Multi-AZ DB cluster 선택:
writer 1대 + readable reader 2대
준동기 commit과 reader endpoint
failover 안정성 + 읽기 분산, ReplicaLag 관측 필요
Read Replica 추가:
replica instance 1대 추가
읽기 부하 분산 가능
ReplicaLag 관측과 라우팅 복잡도 증가
RDS Proxy 추가:
proxy 과금 추가
connection storm과 failover 영향 완화 가능

이 예시는 “싼 구성”을 고르는 표가 아니다. 운영 DB 비용은 안정성 구매이기도 하다. 프로덕션에서 Multi-AZ를 끄면 청구액은 줄지만 장애 시 수동 복구와 데이터 손실 위험이 커진다. 반대로 개발 DB에 Multi-AZ, 큰 instance, 긴 snapshot 보관을 그대로 두면 학습·실험 환경이 프로덕션 비용 구조를 따라가 버린다.

13. 선택 기준 — RDS, Aurora, NoSQL은 첫 질문이 다르다

섹션 제목: “13. 선택 기준 — RDS, Aurora, NoSQL은 첫 질문이 다르다”

이 문서는 RDS Basics이므로 NoSQL이나 Aurora가 본문을 지배하면 안 된다. 다만 선택 기준은 필요하다.

선택지먼저 묻는 질문어울리는 상황
RDS PostgreSQL/MySQL관계, JOIN, 트랜잭션, SQL 제약이 핵심인가?사용자, 주문, 결제, 재고, 백오피스처럼 정확한 쓰기와 관계 모델이 중요한 데이터
AuroraRDS 호환 API를 쓰면서 더 높은 가용성·확장성·스토리지 구조가 필요한가?DB가 이미 병목이고 Aurora의 비용과 제약을 받아들일 수 있는 프로덕션
DynamoDB/MongoDB접근 패턴이 key-value/document 중심이고 수평 확장과 낮은 지연이 더 중요한가?단일 key 조회, 이벤트 상태, 세션성 데이터, 초당 매우 큰 단순 읽기/쓰기
EC2 자가 관리관리형 제약이 제품 요구사항을 막는가?특수 엔진, OS 수준 제어, RDS 미지원 버전이나 확장이 필수인 경우

가장 흔한 오해는 “트래픽이 많으면 NoSQL”이다. 트래픽이 많아도 결제 정합성, 재고 차감, 복잡한 조회, 운영자가 직접 SQL로 확인해야 하는 데이터라면 RDS나 Aurora가 더 단순할 수 있다. 반대로 관계형 모델이 거의 없고 단일 key 접근 패턴이 명확하다면 RDS의 JOIN 능력은 장점보다 비용이 될 수 있다.

긴 runbook을 외우는 대신 증상에서 개념으로 돌아가는 표를 만든다.

증상의미먼저 의심할 개념
too many connections전체 애플리케이션 pool 수요가 DB 한도를 넘었다Task 수 × pool max, max_connections, RDS Proxy
failover 후 일부 프로세스만 계속 실패DNS cache나 pool stale socket이 남았다endpoint, DNS TTL, idle timeout, RDS Proxy
방금 쓴 데이터가 Read Replica에서 안 보임비동기 복제 지연으로 stale read가 발생했다Read Replica, ReplicaLag, primary 라우팅
Multi-AZ DB cluster reader가 writer보다 늦다준동기 확인은 두 reader 모두의 apply 완료를 뜻하지 않는다cluster ReplicaLag, reader/writer endpoint, 최신성 요구
DB 연결 timeout네트워크 경로 또는 SG 규칙이 막혔다Private Subnet, RDS SG, SG-as-source, Route Table
CPU는 낮은데 API가 느림lock wait, I/O wait, connection wait 가능성Database Insights, Top SQL, wait event
RDS 비용이 갑자기 증가storage autoscaling, snapshot 누적, replica/Multi-AZ 비용 가능성storage, backup retention, snapshot inventory
Parameter Group 값을 바꿨는데 효과가 없음재시작 필요 파라미터이거나 다른 group이 붙어 있다dynamic/static parameter, pending-reboot
RDS Proxy를 붙였는데 연결 수가 별로 줄지 않음pinning 때문에 multiplexing이 작동하지 않는다session state, DatabaseConnectionsCurrentlySessionPinned
PITR 복원은 됐지만 어떤 DB로 전환해야 할지 모름백업 기능은 있었지만 복구 절차와 검증 기준이 없었다RPO/RTO, 복구 리허설, 데이터 비교

이 표는 운영 절차를 대체하지 않는다. 대신 첫 10분 동안 “어떤 개념이 깨졌는지”를 좁히게 해 준다. 실제 명령은 팀의 IaC, 콘솔 권한, 모니터링 도구에 맞춰 달라진다.

15. 선택 부록 — 절차는 짧게 확인한다

섹션 제목: “15. 선택 부록 — 절차는 짧게 확인한다”
콘솔에서 RDS 기본 상태 확인
  1. RDS → Databases → 대상 DB를 연다.
  2. Engine, DB instance class, Storage, Multi-AZ, Publicly accessible 값을 본다.
  3. Connectivity & security에서 VPC, Subnet group, Security Group, endpoint를 확인한다.
  4. Monitoring에서 DatabaseConnections, CPUUtilization, FreeStorageSpace, ReadIOPS/WriteIOPS를 본다.
  5. Maintenance & backups에서 backup retention period와 latest restorable time을 확인한다.
  6. 배포 환경의 DATABASE_URL 또는 secret 값이 실제 RDS endpoint를 가리키는지 확인한다. localhost, 오래된 dev endpoint, 잘못된 port는 네트워크 장애처럼 보일 수 있다.

첫 회독의 목표는 값을 바꾸는 것이 아니라 “이 DB가 어느 VPC에 있고, 누가 접속할 수 있고, 복구 가능 시점은 어디인가”를 말할 수 있게 되는 것이다.

연결 수 초과를 계산하는 최소 절차
  1. 현재 ECS/EC2/Lambda 등 DB client 프로세스 수를 센다.
  2. 각 프로세스의 connection pool max를 확인한다.
  3. 프로세스 수 × pool max를 계산한다.
  4. RDS의 DatabaseConnections와 Parameter Group의 max_connections를 비교한다.
  5. 배포 중 일시적으로 늘어나는 task 수와 운영 여유분을 더한다.
  6. 단기적으로 pool max를 낮추고, 장기적으로 RDS Proxy나 인스턴스 증설, 쿼리/트랜잭션 시간 단축을 검토한다.
Read Replica stale read 1차 확인
  1. 해당 조회가 replica endpoint로 가는지 primary endpoint로 가는지 확인한다.
  2. CloudWatch에서 ReplicaLag를 본다.
  3. 최신성이 필요한 엔티티인지 분류한다. 재고, 잔액, 권한, 결제 상태는 primary 후보가 된다.
  4. lag가 임계값을 넘으면 해당 조회만 primary로 라우팅하거나 replica 사용을 일시적으로 줄인다.
  5. replica가 필요한 이유가 읽기 부하인지, 리포트 격리인지, 백업성 조회인지 다시 확인한다.
failover 대비 점검
  1. Multi-AZ 여부와 DB instance deployment인지 DB cluster인지 확인한다.
  2. 애플리케이션 런타임의 DNS TTL을 확인한다. JVM은 networkaddress.cache.ttl을 특히 본다.
  3. pool idle timeout과 connection lifetime이 너무 길지 않은지 본다.
  4. DB 요청 retry가 idempotent하게 설계됐는지 확인한다.
  5. RDS Proxy를 쓰는 경우 pinning metric을 함께 본다.
  • 팀 RDS 하나를 골라 Engine, instance class, Multi-AZ, Publicly accessible, backup retention period를 적어 본다.
  • RDS Security Group inbound에 0.0.0.0/0이 아니라 애플리케이션 SG가 source로 들어 있는지 확인한다.
  • 애플리케이션의 pool max와 실행 task 수를 곱해 현재 최대 연결 수요를 계산한다.
  • CloudWatch에서 DatabaseConnections가 배포 시간에 어떻게 변하는지 본다.
  • Read Replica가 있다면 ReplicaLag와 replica endpoint 사용 위치를 확인한다.
  • 자동 백업의 latest restorable time과 수동 snapshot 목록을 비교한다.
  • Database Insights 또는 Performance Insights 계열 화면에서 Top SQL과 wait event가 무엇을 뜻하는지 하나만 읽어 본다.
개념 A개념 B차이점
RDSEC2 자가 관리 DBRDS는 백업·패치·failover 운영을 관리형으로 제공하고, EC2는 직접 운영한다
Multi-AZ DB instanceMulti-AZ DB clusterinstance는 동기식 비가독 standby 1개, cluster는 준동기식 readable reader 2개다
Multi-AZ DB instanceRead Replica전자는 장애 대비, 후자는 비동기 읽기 분산이다
EndpointIP addressendpoint는 DNS 이름이고, failover 때 가리키는 IP가 바뀔 수 있다
자동 백업수동 Snapshot자동 백업은 보관 기간을 따르고, snapshot은 삭제 전까지 남는다
PITRSnapshot restorePITR은 특정 시점 복원, snapshot은 snapshot 생성 시점 복원이다
Parameter Group애플리케이션 설정Parameter Group은 DB 엔진 설정이고, pool max는 앱 설정이다
Connection PoolRDS Proxypool은 앱 프로세스 안의 연결 재사용, RDS Proxy는 DB 앞의 관리형 프록시다
Database InsightsQuery profilerDatabase Insights는 DB load와 wait event 관측, profiler는 코드/쿼리 레벨 분석이다

RDS 복습 체크리스트

  • RDS를 관계형 DB 운영 자동화 계층으로 설명하고, AWS 책임과 팀 책임을 구분할 수 있다.
  • Multi-AZ DB instance의 동기식 비가독 standby와 Multi-AZ DB cluster의 준동기식 readable reader 2개를 구분할 수 있다.
  • Multi-AZ DB instance가 장애 대비이고, 별도 Read Replica가 비동기 읽기 분산이라는 차이를 말할 수 있다.
  • failover 시간이 RDS 승격 시간뿐 아니라 DNS TTL, pool 재연결, retry 정책의 합으로 체감된다는 점을 설명할 수 있다.
  • PITR, 자동 백업, 수동 snapshot의 차이와 복구 시 새 DB 검증이 필요한 이유를 말할 수 있다.
  • ECS Task 수와 connection pool max를 곱해 DB 최대 연결 수요를 계산할 수 있다.
  • RDS Proxy의 multiplexing 효과와 pinning 때문에 효과가 줄어드는 경우를 설명할 수 있다.
  • RDS를 Private/DB Subnet에 두고 SG-as-source로 애플리케이션 SG만 허용해야 하는 이유를 설명할 수 있다.
  • ReplicaLag, DatabaseConnections, DB Load, Top SQL, FreeStorageSpace가 어떤 실패 신호와 연결되는지 말할 수 있다.

추가 학습 키워드: Aurora, RDS Proxy, PITR, Read Replica, ReplicaLag, Parameter Group, Database Insights, Slow Query Log, Connection Pooling, DB Migration Service(DMS), Secrets Manager

  1. RDS는 SQL DB를 새로 발명한 서비스가 아니라, 관계형 DB 운영의 백업·패치·failover·관측 일부를 AWS 관리형 경계로 옮긴 서비스다.
  2. Multi-AZ DB instance는 동기식 비가독 standby 1개를, Multi-AZ DB cluster는 준동기식 readable reader 2개를 둔다. 별도 Read Replica는 비동기 읽기 확장이라 stale read와 ReplicaLag를 함께 본다.
  3. failover 체감 시간은 RDS 승격 시간만이 아니라 endpoint DNS TTL, connection pool, retry 정책까지 포함한다.
  4. 연결 장애는 Private Subnet, Security Group, endpoint, pool 크기, parameter group을 나누어 본다. Task 수 × pool max 계산은 반드시 손으로 해 본다.
  5. RDS 비용과 안정성은 Multi-AZ, replica, storage autoscaling, snapshot, RDS Proxy, 개발 DB idle 시간의 합으로 결정된다.