“Postgres가 느린 게 아니라 스토리지가 문제다” DB 성능 병목의 숨겨진 진실

📌 3줄 핵심 요약

  • Postgres 성능 저하의 주요 원인은 쿼리나 엔진 자체가 아닌 클라우드 블록 스토리지의 I/O 지연 시간입니다.
  • AWS EBS 등 네트워크 부착 스토리지는 IOPS와 대역폭 스로틀링(Throttling)으로 인해 극심한 병목을 유발합니다.
  • 인덱스 최적화 전에 스토리지 계층(NVMe, 캐싱, 볼륨 타입)을 점검해야 근본적인 처리량을 획기적으로 개선할 수 있습니다.

데이터베이스 조회가 갑자기 느려지면 개발자들이 가장 먼저 하는 일은 무엇일까요? 보통 EXPLAIN ANALYZE를 돌리며 인덱스를 추가하거나 복잡한 SQL 쿼리를 리팩터링하곤 합니다. 하지만 최근 해커뉴스(Hacker News)와 글로벌 엔지니어링 커뮤니티에서 폭발적인 공감을 얻은 발표에서는 전혀 다른 진단을 내놓았습니다.

“Postgres isn’t slow, your storage is (포스트그레스가 느린 것이 아니라, 당신의 스토리지가 느린 것입니다)”

1. 쿼리 튜닝이 답이 아닌 이유: 스토리지 I/O의 실체

현대 클라우드 환경(AWS, GCP, Azure 등)에서 대부분의 데이터베이스는 물리 서버에 직접 연결된 디스크가 아니라 네트워크를 통해 연결된 가상 블록 스토리지(예: AWS EBS)를 사용합니다. 이 구조는 확장성과 백업 편의성은 뛰어나지만, 데이터베이스 성능 관점에서는 치명적인 약점을 가집니다.

네트워크 지연과 블록 스토리지의 한계

로컬 NVMe SSD의 레이턴시가 수십 마이크로초(µs) 수준인 반면, 네트워크 부착 스토리지는 밀리초(ms) 단위의 왕복 지연이 발생합니다. PostgreSQL이 트랜잭션 커밋을 위해 WAL(Write-Ahead Logging)을 디스크에 동기화(fsync)할 때마다 이 네트워크 지연이 누적되며 데이터베이스 전체가 멈칫거리게 됩니다.

⚠️ 흔히 저지르는 실수: IOPS만 높이면 해결된다?

IOPS 수치만 높인다고 능사가 아닙니다. 블록 사이즈, 인스턴스 자체의 EBS 대역폭(EBS-Optimized Limit), 그리고 지연 시간(Tail Latency)이 복합적으로 얽혀 스로틀링이 발생할 수 있습니다.

2. 로컬 스토리지 vs 클라우드 네트워크 스토리지 비교

실제 스토리지 아키텍처에 따른 성능 차이를 한눈에 정리하면 다음과 같습니다.

구분 로컬 NVMe SSD (인스턴스 스토어) 범용 클라우드 볼륨 (gp3) 프로비저닝 볼륨 (io2)
접근 방식 PCIe 직결 (로컬 버스) 네트워크 부착 스토리지 고성능 네트워크 부착
평균 레이턴시 < 0.1ms 1ms ~ 5ms+ sub-millisecond
비용 대비 처리량 압도적 가성비 저렴하나 병목 위험 비용 부담 큼
데이터 영속성 인스턴스 중지 시 휘발 영구 보존 및 스냅샷 지원 높은 99.999% 내구성

3. DB 병목을 탈출하는 실전 최적화 가이드

💡 실전 꿀팁: 지금 당장 점검해야 할 3가지

  • 메트릭 확인: iostat -x 1 또는 CloudWatch의 VolumeQueueLength, EBSIOBalance%를 확인하여 버스트 크레딧 소진 여부를 점검하세요.
  • shared_buffers 상향: 빈번한 I/O를 막기 위해 PostgreSQL의 shared_buffers를 시스템 RAM의 25~40% 수준으로 충분히 확보하세요.
  • WAL 배치 커밋: 높은 쓰기 환경이라면 synchronous_commit = off(허용 가능한 범위 내) 혹은 커밋 딜레이 설정을 고려해 디스크 fsync 횟수를 줄이세요.

4. 자주 묻는 질문 (FAQ)

Q1. 로컬 NVMe는 인스턴스가 꺼지면 데이터가 날아가는데 어떻게 쓰나요?

운영 환경에서는 로컬 NVMe를 읽기 전용 복제본(Read Replica)의 스토리지나 임시 작업(temp_tablespace) 용도로 활용하거나, 스트리밍 복제(Streaming Replication)와 주기적 백업(WAL-G, pgBackRest)을 결합하여 영속성 문제를 해결합니다.

Q2. AWS RDS를 쓰면 스토리지 문제를 피할 수 있나요?

아닙니다. AWS RDS 역시 내부적으로 EBS 볼륨을 사용합니다. 할당된 스토리지 크기가 너무 작으면 기본 IOPS가 낮게 설정되어 성능 저하가 발생하므로, gp3 볼륨의 기본 제공량(3000 IOPS, 125MB/s) 이상이 필요한지 트래픽 패턴을 모니터링해야 합니다.

Q3. 쿼리 최적화는 전혀 필요 없는 건가요?

아닙니다. 비효율적인 풀 테이블 스캔(Seq Scan)은 스토리지에서 불필요하게 많은 블록을 읽어오게 만듭니다. 즉, 비효율적인 쿼리가 스토리지 I/O 병목을 촉발하는 트리거 역할을 하므로, 쿼리 최적화와 스토리지 인프라 튜닝은 반드시 병행되어야 합니다.

댓글 남기기