brunch

RDS 데이터베이스 서버 스펙다운 사례

by 멘토사피엔스
RDS의 스펙을 다운스케일하면 비용을 많이 절감할 수 있습니다. 특히 같은 패밀리의 스펙을 한 단계 낮추는 것만으로 서버 유지 비용이 50% 절감됩니다.
인스턴스의 스펙을 낮추기 위해 CPU, 메모리 및 Read/Write IOPS를 모니터링해야 합니다.
아래는 개발환경에서 스펙을 다운스케일한 전 후의 결과를 모니터링한 실무 사례를 설명하였습니다.


RDS에서 Aurora 클러스터를 사용하고 있는 가운데, 개발환경에서 사용하는 데이터베이스를 스펙다운한 실무 사례입니다.


RDS의 비용은 크게 3가지 관점에서 볼 수 있습니다. 서버 유지비용, IO 비용, 그리고 스토리지 비용인데요. 그 중에서 대부분은 서버 유지비용의 비율이 높은 편입니다. 서버 유지비용을 낮추기 위해서는 운영이 가능한 가운데 적합하게 낮은 스펙을 고려할 수 있어야 합니다.


해당 시점에 개발환경에서는 db.r6g.xlarge를 사용하고 있었습니다. 그리고 목표는 한 단계 스펙다운을 해서 db.r6g.large를 사용하게끔 하는 것이었습니다. 결론적으로 스펙다운은 실행되었고 기존 비용의 절반 값으로 비용을 낮출 수 있었습니다.


목표


현재 - db.r6g.xlarge

목표 - db.r6g.large


스펙비교

스크린샷 2025-05-10 오후 7.26.10.png


인스턴스 유형별 비용은 아래 사이트에서 편리하게 확인할 수 있습니다.


db.r6g.xlarge는 하루 $15.048, 한달에 $457.71이 서버 유지비용으로 지출됩니다. 한 단계 스펙다운을 할 수 있다면 월 $228.49로 월 $229, 50% 비용 절감을 할 수 있습니다.


스펙다운을 하게 되면 위 스펙비교에서 볼 수 있듯이 CPU와 메모리가 두배로 낮아집니다. 해당 환경에서 운영이 가능한지를 확인해야 합니다.


결론


지표로 파악 시 메모리 외 큰 문제 없어 보였습니다. 단 메모리는 버퍼풀 축소가 이루어지게 되므로 버퍼 히트율이 떨어지게 되면 CPU, IO 등 다른 지표의 성능에 영향을 미칠 수 있습니다.


따라서 스펙을 낮춘 뒤에 전체적으로 지표가 문제 없는지 확인하고 롤백을 결정할 필요가 있습니다.

캐시 적중률이 최소 95% 유지될 필요 있음

다른 지표, CPU, Write/Read IOPS가 일정수준 이상 증가하지 않아야 함


다만 아래 사유로 버퍼 히트율이 크게 떨어지지 않을 것이라 추측했습니다.

해당 데이터베이스로 오랜 기간 유지했으므로 오래된 캐시가 남아있다면 개발을 해온 과정에 자주 사용되지 않는 쿼리들이 메모리에 있을 가능성이 있음


검토해야 할 지표


크게 검토한 지표는 아래와 같습니다.

CPU

메모리

디스크 IOPS

네트워크 트래픽

데이터베이스 연결 수


지표 분석


CPU 사용률

CPU를 얼마나 쓰고 있는지를 확인합니다.


1) CPUUtilization

권장 임계치는 평균 CPU 사용률이 50% 이하이고 피크 사용률이 70% 이하입니다.

img.png

분석 결과

평균 10%, 피크 시 cpu 사용이 45%로 문제 없다고 판단되었습니다.



메모리

메모리 부족으로 인한 스왑이나 OOM(Out of Memory) 발생 여부를 확인합니다.


1) FreeableMemory

RDS 인스턴스에서 현재 사용 가능한 메모리 양을 의미합니다.

전체 메모리 = OS 사용메모리 + 버퍼캐시 + FreeableMemory

메모리 사용률이 높다면 스펙 축소 시 OOM 발생 가능성이 있습니다.

권장 임계치는 사용 가능한 메모리(FreeableMemory)가 25% 이상입니다.

img.png

분석 결과

다운스케일 후에도 최소 25% 메모리 여유가 있으면 문제 없습니다.

현재 메모리 사용률을 보면 79%로 21%의 여유가 있는 상황입니다. 지표만 본다면 32GB → 16GB로 낮출 경우 위험할 수 있습니다. 단 버퍼로 사용하는 메모리가 20GB이고 Aurora는 버퍼의 크기가 스펙 설정 시 자동할당되는 구조라 문제 발생여부는 테스트해볼 가치 있다고 판단되었습니다.


메모리 관련 추가 분석

메모리와 연관된 다른 지표의 상황을 추가로 확인하고 메모리를 줄일 수 있는 가능성을 검토합니다.


1) 스왑 사용량

분석 결과

현재 20MB로 지속 사용 중으로 이는 메모리가 부족해 디스크를 메모리로 활용하는 상황을 의미하지만 미미한 수준입니다. 스왑이 거의 발생하고 있지 않습니다.


2) Buffer Cache Hit

Buffer 관련 지표를 확인합니다. 특히 Buffer Cache Hit이 95% 이상이어야 합니다.



스크린샷 2025-05-10 오후 8.01.16.png

분석 결과

버퍼 캐시 히트율은 99.89%로 매우 높은 편입니다. 다만 버퍼의 할당된 크기 대부분이 현재 사용되고 있습니다. 이 버퍼에 저장된 많은 수는 현재 사용되지 않을 수도 있다고 판단했습니다.


Buffer 세부 지표 설명

1) Innodb_buffer_pool_pages_total

InnoDB Buffer Pool 메모리 총 크기입니다.

1278208 x 16KB = 20,960,000KB (약 20GB)

2) Innodb_buffer_pool_pages_data

Buffer 사용률입니다.

1277744 / 1278208 x 100 = 99.96%

버퍼는 할당된 크기를 거의 대부분 사용하고 있습니다. 이것은 추가적인 쿼리에 따라 스왑이 발생할 수도 있음을 의미합니다.

3) Innodb_buffer_pool_reads

Buffer Pool에서 데이터를 찾지 못해 디스크에서 읽은 횟수입니다.

893292137로 디스크 I/O가 상당히 많이 발생한 상태입니다.

4) Innodb_buffer_pool_read_requests

메모리에서 데이터를 읽어온 횟수입니다.

5) 캐시 히트율(Hit Ratio)

880260744328 / (880260744328 + 893292137) = 99.89%

메모리 활용이 잘 되고 있어, 디스크 I/O를 최소화하고 있습니다.

버퍼 캐시 히트율 아래의 쿼리로 계산 가능합니다.

6) Innodb_buffer_pool_pages_dirty

수정된 후 아직 디스크에 기록되지 않은 페이지 수입니다.

152로 디스크 쓰기 지연이 없습니다.

7) Innodb_buffer_pool_wait_free

Buffer Pool이 가득차 대기한 횟수입니다.

0으로 메모리 부족 문제는 현재 없다고 볼 수 있습니다.


Buffer Pool 크기 조정

메모리 여유를 확보하기 위해 Buffer Pool 크기를 줄일 필요 있습니다. Buffer Pool은 총 메모리의 70-80%가 적당합니다. 다만 Aurora RDS에서는 스펙에 따라 자동할당되므로 해당 사항을 고려할 수는 없습니다. EC2에서 볼륨을 할당해서 데이터베이스를 활용하거나 기타 케이스를 고려해 다음과 같은 내용을 참조하면 좋습니다.


크기를 낮출 경우 Buffer Pool의 캐시 적중률을 확인해야 합니다.

캐시 적중률이 95% 이하로 떨어지면 성능 저하 가능성이 큽니다.

크기를 낮춘 뒤 디스크 IOPS와 대기 시간 모니터링이 필요합니다.

참조 지표 - CPU, ReadIOPS, WriteIOPS, DiskQueueDepth, Aurora:StorageIOUsage, Aurora:VolumeReadIOPs


RDS의 경우 테스트하기 위해 버퍼풀 크기를 조금씩 줄여가는 방식은 불가능합니다. 스펙다운 후 지켜볼 필요 있습니다. 버퍼풀을 직접 조정하려고 하면 아래와 같은 메시지와 함께 수정이 되지 않습니다. r6g.xlarge 스펙 기준 현재 20G가 할당되어 있습니다.

Variable 'innodb_buffer_pool_size' is a read only variable



캐시 최적화

버퍼크기를 조정하는 것만으로도 캐쉬가 정리될 수 있습니다. LRU 알고리즘에 따라 덜 사용된 페이지부터 제거합니다. 즉, 사용 빈도가 적거나 오래된 페이지부터 제거됩니다.

다만 페이지가 제거될 때는 Dirty Pages(수정된 페이지)가 디스크로 플러시되어 디스크 I/O가 급증할 수 있습니다.

참고로 오래된 데이터 페이지를 파악하거나 비효율적인 캐시 테이블은 아래와 같은 쿼리를 통해 확인이 가능합니다.



디스크 IOPS (ReadIOPS, WriteIOPS)

디스크 읽기/쓰기 IOPS의 성능 저하 가능성을 파악해야 합니다. 주로 ReadIOPS, WriteIOPS를 확인합니다.

권장 임계치로는 평균 IOPS가 EBS IOPS 한계보다 낮아야 합니다. 일반적인 gp3 의 경우 기본 3000 IOPS, 최대 16000 IOPS까지 처리 가능합니다. 그리고 디스크 큐 깊이(DiskQueueDepth)가 낮은 수준이어야 합니다.

IOPS는 스토리지와 관련 있기 때문에 CPU와 메모리 감소가 직접적인 IOPS 저하를 유발하지는 않습니다. 다만, 데이터 처리 성능과 캐싱 효율이 줄어들어 IOPS 증가 가능성이 있습니다. ReadIOPS가 300이하, WriteIOPS가 50 이하면 안정적 유지가 가능합니다.

분석 결과

현재 ReadIOPS가 평균 80, 맥스 350 이고 WriteIOPS는 평균 10, 맥스 350로 문제 없어 보인다고 판단됩니다.


네트워크 트래픽

네트워크 대역폭 사용량을 확인하여 성능 저하 여부를 판단합니다. 주로 NetworkReceiveThroughput, NetworkTransmitThroughput 지표를 확인합니다.

권장 임계치로 평균 네트워크 대역폭이 인스턴스의 최대 처리량 대비 70% 이하라면 문제 없습니다.


분석 결과

NetworkReceiveThroughput이 평균 24k, 맥스 80k

NetworkTransmitThroughput이 평균 100k, 맥스 300k

최대 대역폭 10Gbps인 기본 Aurora 인스턴스의 네트워크 성능을 고려할 때 현재 수치는 매우 낮다고 볼 수 있습니다


데이터베이스 연결 수

애플리케이션에서 동시에 접속하는 커넥션 수를 확인합니다. 주로 DatabaseConnections를 확인합니다.

권장 임계치로 동시 연결 수가 인스턴스 한계치의 70% 이하면 됩니다.


분석 결과

xlarge의 최대 동시 연결 수는 4000이고 연결수는 300으로 약 7.5% 범위로 문제 없습니다.


다운스케일 후 지표 변화


CPU

평균 30%, 피크 시에 70% 수준을 기록하고 있습니다.

img.png


메모리

Freeable 메모리는 5.3G 선에서 줄어들지 않고 잘 유지되고 있습니다.

img.png


버퍼풀 지표

다운스케일 이전의 지표와 비교 및 비교분석한 내용입니다.

스크린샷 2025-05-10 오후 8.28.03.png


버퍼관점에서 데이터베이스 성능에는 문제가 없습니다. Innodb_buffer_pool_wait_free이 0이므로 버퍼 부족으로 대기한적이 없다는 뜻입니다. Innodb_buffer_pool_pages_dirty와 Innodb_buffer_pool_bytes_dirty 역시 정상 수준으로 쓰기 작업도 정상적입니다. Innodb_buffer_pool_pages_flushed 역시 동일한데 이는 메모리 쓰기 플러스기 급격히 늘지 않았고 디스크 부담이 적음을 의미합니다.

또한 버퍼 캐시 히트율은 99.68%를 기록했으며 이는 디스크 IO에 거의 의존하지 않음을 뜻합니다.

다만 Innodb_buffer_pool_pages_free 의 값이 2로 매우 낮습니다. 이는 버퍼풀에서 아직 사용되지 않은 빈 페이지 수가 거의 없음을 의미합니다. 하나의 페이지 크기는 16KB로 Innodb_buffer_pool_pages_total 대비 0.0004% 수준입니다. 버퍼 풀이 거의 꽉 차있으므로 즉지 적재 가능한 비어 있는 슬롯이 없다고 볼 수 있습니다. 이 자체가 문제는 아니지만, 트래픽이 증가하거나 대량 쿼리가 발생할 경우 wait_free가 발생할 수도 있습니다. Innodb_buffer_pool_pages_dirty 또는 Innodb_buffer_pool_wait_free 값에 변화가 있는지 모니터링할 필요가 있습니다.


디스크 IOPS (ReadIOPS, WriteIOPS)

Read IOPS의 경우 100 이하로 낮은 수치를 보이고 있으나 간혹 2000-5000으로 튈 경우가 모니터링되었습니다. 일주일에 2회 발생했기 때문에 지켜볼 필요가 있습니다.

Write IOPS는 50이하로 여전히 낮은 수치를 보이는 가운데 320 정도로 튀는 경우가 있습니다.


데이터베이스 연결 수

300 정도로 특별히 더 늘어난 현상은 없습니다.


정리


스펙다운은 안정적으로 이루어졌습니다. 비용절감을 위해 무작정 스펙다운을 하기보다 현재 지표를 면밀히 살펴보는 것, 그리고 스펙변경 이후 모니터링을 꾸준히 해서 CPU, 메모리를 비롯해 전반적인 성능이 문제 없는지 모니터링을 해볼 필요가 있습니다. 저희 팀에서는 아래 2가지를 지속적으로 모니터링할 예정입니다.


디스크 IOPS 중 Read IOPS가 간혹 높게 치는 경우가 있어 해당 케이스를 좀 더 모니터링해 볼 필요가 있습니다.

개발 환경이라 트래픽이 예상과 다르게 증가할 가능성은 낮습니다 다만, 쓰기 대기가 발생하거나(Innodb_buffer_pool_wait_free) 수정되었는데도 디스크에 아직 쓰여지지 않은 페이지 수가 있는지(Innodb_buffer_pool_pages_dirty) 확인해볼 필요가 있습니다.


현재 기준으로 다시 업스케일을 할 필요는 없다고 판단되어 비용절감은 성공적으로 이루어졌습니다.







FinOps 커뮤니티에 함께 하실래요?


저는 최근 48%, $36000의 AWS 비용절감을 달성했습니다.

클라우드 비용을 효율화하고 싶은 분들, 비슷한 고민을 나누고 싶다면 제가 운영 중인 AWS-FINOPS-KR Slack 커뮤니티에 참여하세요. 실제 절감 사례, 질문, 전략 공유를 나누실 수 있습니다.


⇒ [FinOps Slack 참여하기]

keyword
매거진의 이전글MySQL 5.7 → 8.0 버전업 사례