OpenAI: PostgreSQL를 다음 단계로 확장하기

6 hours ago 2

  • OpenAIPostgreSQL을 샤딩 없이 사용하면서도 수억 명의 사용자 트래픽을 효과적으로 처리하는 방법을 PGConf.dev 2025에서 공유함
  • 쓰기 병목 문제를 해결하기 위해 쓰기 분산, 쿼리 최적화, 스키마 관리 등 다양한 접근 방식을 도입함
  • 주요 이슈로 MVCC 디자인의 테이블/인덱스 팽창, WAL로 인한 복제 지연 등 PostgreSQL 구조상의 한계와 운영 난점을 언급
  • 읽기 부하 분산과 긴 트랜잭션 제한, ORM 최소화 등의 쿼리 최적화 전략이 핵심
  • OpenAI는 지리적으로 분산된 40개 이상의 복제본을 통해 100만 QPS를 달성하고, 장애 발생 시에도 높은 가용성을 보장함

OpenAI의 PostgreSQL 대규모 확장 사례

배경

  • OpenAI의 핵심 서비스 다수가 PostgreSQL에 의존함
  • 데이터베이스 장애가 발생할 경우 서비스 전체에 직접적 영향이 미침
  • 과거 ChatGPT를 비롯한 주요 서비스에서 PostgreSQL 문제로 인해 중단 사례가 발생한 경험 있음
  • OpenAI는 Azure 관리형 데이터베이스에서 Primary-Replica 아키텍처(단일 Primary + 40개 이상 Replicas) 를 운영함
  • 월간 5억 명의 활성 사용자를 상대하는 환경에서 확장성이 비즈니스 성공에 핵심 요소로 작동함

주요 과제

  • 읽기 트래픽은 다수의 Replica로 분산 가능하나, 쓰기 요청이 단일 Primary에 집중되어 병목 발생
  • 주요 개선점
    • 가능한 모든 쓰기 요청을 오프로딩하여 분산
    • 신규 서비스의 Primary DB 추가 접속 최소화
  • MVCC(다중 버전 동시성 제어) 구조상 테이블/인덱스 팽창, 복잡한 가비지 컬렉션 튜닝, 인덱스 가시성 체크 등의 단점 존재
  • Replica 수 증가 시 WAL(Write-Ahead Logging) 트래픽 역시 급증, 네트워크 대역폭이 또다른 병목 요인으로 대두됨

대응 방안

Primary 데이터베이스 부하 분산

  • 쓰기 부하 예측 및 완화:
    • 모든 가능한 쓰기 오프로딩
    • 불필요한 애플리케이션 레벨 쓰기 방지
    • Lazy Write 적용, 데이터 백필 주기 조절
  • 읽기 부하는 최대한 Replica로 분산, 불가피하게 Primary에서 처리할 경우는 높은 효율성 요구

쿼리 최적화

  • 장기 트랜잭션이 시스템 자원을 장시간 점유, 가비지 컬렉션 지연 초래
  • 세션/쿼리/클라이언트별 Timeout 적용, Idle in transaction 세션 제한
  • ORM 사용 시 비효율성 증가 가능성을 명시, 조심하여 사용 권장
  • 복잡한 multi-join 쿼리(예: 12개 테이블 조인) 최적화 수행

단일 장애점(SPOF) 대응

  • Primary는 장애 시 쓰기 불가, Replicas는 일부 장애가 나도 읽기 연속성 보장
  • 중요 요청(고우선)은 전용 Replica에서 처리, 저우선 요청의 간섭 최소화

스키마 관리

  • 신규 테이블 생성, 신규 워크로드 도입은 클러스터에 제한
  • 컬럼 추가/제거는 5초 제한 내 경량 작업만 허용, 전체 테이블 재작성 요구 작업은 불가
  • 인덱스 생성/제거는 CONCURRENTLY 옵션으로만 허용
  • 1초 이상 소요되는 장기 쿼리가 스키마 변경을 지속적으로 블로킹하는 문제가 발생, 애플리케이션 차원에서 이러한 쿼리 최적화/오프로딩 필요

운영 결과

  • 전체 클러스터에서 100만 QPS(읽기+쓰기) 처리, OpenAI 주요 서비스 지원
  • 40여 개 Replica 추가에도 복제 지연 증가 없음
  • 다양한 Region에 Read-only Replica 배치, 저지연 유지
  • 최근 9개월 간 PostgreSQL 관련 SEV0 장애 1건만 발생
  • 향후 성장 여력 충족 위한 용량 확보

장애 사례

  • 캐시 실패에 따른 cascading effect
  • 높은 CPU 점유 시 WALSender 프로세스가 WAL 전송을 멈추고 루프 상태에 빠지는 버그 → 복제 지연 발생

PostgreSQL에 제안된 기능 개선 요청

  1. 인덱스 관리: 불필요한 인덱스의 안전한 비활성화를 위한 Disable 기능 제안(삭제 전 위험 최소화 목적)
  2. 관측성: p95, p99 등 latency 히스토그램/분위수 기반 지표 제공 요청
  3. 스키마 변경 이력: DDL 등 스키마 변경 내역 저장 기능 요구
  4. 모니터링 뷰 의미 명확화: 특정 세션이 ClientRead 상태로 오랜 시간 유지되는 현상에 대한 원인 및 대응 문의
  5. 기본 파라미터 최적화: PostgreSQL의 기본값이 지나치게 보수적, 더 나은 기본값 혹은 휴리스틱 도입 요청

Lao Feng의 코멘트

  • 이러한 극한 환경에서의 OpenAI 확장 전략은 코어 PostgreSQL 개발자에게 실전 활용 사례로 유의미함
  • 중국 Tantan 등 대규모 서비스에서도 유사 경험(Replica 33개, 40만 QPS, 애플리케이션 측 샤딩 도입) 존재
  • 오늘날 고성능 HW 환경에서는 OpenAI처럼 단일 PostgreSQL 클러스터로도 공격적 확장 현실화, 분산 DB가 꼭 필요한 것은 아님을 시사
  • OpenAI는 Azure 관리형 PostgreSQL, 40개 이상의 Replica, cross-region 배포, Kubernetes + PgBouncer 활용
  • Azure PostgreSQL 팀의 집중 지원 받지만, 여전히 운영 측면의 애플리케이션/DBA 실력과 관찰성이 필수
  • Datadog 통한 모니터링, 성능 및 비용 부담 언급
  • 운영 노하우, 실패 경험, DBA 자산이 서비스 품질에 핵심

Lao Feng Q&A

인덱스 비활성화 기능

  • PostgreSQL의 내부적으로 indisvalid 필드로 index 비활성화 가능(단, superuser 권한 필요, RDS 환경에서는 제한)
  • 실질적 대안은 모니터링 통해 index 사용 여부 확인 후 안전하게 삭제하는 방안

관측성 확장: P95/P99 latency

  • pg_stat_statements의 분위수 지표 지원은 메모리 오버헤드로 인해 어렵고, pg_stat_monitor/eBPF/애플리케이션 계층에서의 latency 모니터링 등 우회 방법 존재
  • Azure 관리형 PostgreSQL 환경에서는 일부 옵션(서버 접근, eBPF 등) 미지원

스키마 변경 이력

  • 로그 파일, pgaudit, CREATE EVENT TRIGGER, pg_ddl_historization 등 활용 가능(단, superuser 권한 필요, Azure RDS 지원 제한)
  • 요구하는 형태는 쿼리 가능한 시스템 뷰/테이블 형태의 이력 저장

모니터링 뷰 의미

  • State=Active + WaitEvent=ClientRead 조합은 Statement 실행 도중 클라이언트 입력 대기 상태를 의미하며, 꼭 버그가 아닌 다양한 원인 존재
  • 연결 유지 시간 제한(HAProxy 등 네트워크 계층에서의 연결 만료 설정, 클라이언트 connection pool 수명 관리 등)으로 부작용 최소화 가능, Azure에서는 해당 기능 지원 미확실

기본 파라미터

  • PostgreSQL의 기본값이 지나치게 보수적이나, 서비스별 세밀한 휴리스틱 혹은 자동화 파라미터 튜닝(RDS, Pigsty 등)으로 보완 가능
  • 향후 PostgreSQL 툴 내에서 HW 사양 자동 감지-적용 기능이 도입된다면 현장 부담 완화 예상

자체 운영(셀프 호스팅) 옵션

  • 실질적 운영상의 문제는 PostgreSQL 자체보다는 Azure 관리형 한계에서 파생됨
  • IaaS 환경 등에서 자체적으로 NVMe SSD 기반 PostgreSQL 클러스터 구축(Pigsty 등)시 기능적/운영상 유연성 증가
  • Pigsty와 같은 솔루션을 활용하면 OpenAI 요구 대부분 선제적으로 해결 가능하므로, 규모와 요구에 따라 도입 고려 여지 언급

Read Entire Article