6P by GN⁺ 10시간전 | ★ favorite | 댓글 1개
  • 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 요구 대부분 선제적으로 해결 가능하므로, 규모와 요구에 따라 도입 고려 여지 언급
Hacker News 의견
  • 지난주 PGConf에 참가해서 이 발표가 가장 많은 사람들이 몰렸던 세션 중 하나였다는 점이 인상적이었음, 특히 대부분의 세션이 Postgres 자체 개발에 초점을 맞췄던 내향적 컨퍼런스였던 만큼 이 사례 발표가 신선하게 느껴졌음. 많은 팀이 제품이 성공적으로 성장할 때 스택의 특정 부분을 어떻게 확장할지 깊이 알지 못한다는 것을 항상 기억해야 할 필요성, 이 발표는 작은 팀이 어떻게 문제를 극복하며 학습해 나가는지 보여주는 멋진 이야기였다는 평가. "이렇게 하면 안 돼요?" 같은 단순화된 반응보다는, 실제 사용자 이야기로 성장 과정과 제품의 높은 인기를 생생하게 보여줬다는 점에서 내부 개발자 위주의 행사에 딱 맞는 세션이라는 생각. 이 발표의 핵심 메시지는 쓰기 작업이 많지 않으면, 읽기 전용 노드(read replicas)와 단일 마스터 구조만으로도 Postgres를 어마어마한 읽기 처리량까지 확장할 수 있다는 것이라는 점. 이 메시지가야말로 대부분 앱에 해당하는 내용이라는 주장. Q&A 시간에는 주로 Postgres 코어 개발자들이 사용사례를 배우고자 하는 질문 위주였고, 비판하려는 의도는 거의 없었으며 Postgres 커뮤니티가 정말 친절하고 열린 분위기라는 소감

    • "쓰기 작업이 많지 않다면 단일 마스터와 읽기 전용 레플리카로 Postgres의 읽기 처리량을 크게 확장할 수 있다"는 메시지에 대해, 시스템 디자인 면접을 보며 느낀 건 너무 많은 지원자가 초당 5회 읽기 수준의 간단한 시스템에도 거대한 분산 구조나 결국 일관성이 깨어지는 시스템부터 도입하려 한다는 점이라는 말. 천만 명 유저도 사실 그렇게 큰 규모는 아니라는 주장. 업계 전체가 수평확장에만 몰두하는 동안, 실제 하드웨어가 상상 이상으로 빨라지고 커졌다는 점을 더 많은 이가 인지해야 한다는 바람. Amazon에서 32TB 램 서버를 임대할 수 있는 세상이라는 설명. 규모가 커진 상황에서도 ACID 보장은 여전히 너무 소중하다는 강조

    • 발표 내용이 정말 전달하고 싶었던 핵심 메시지였다며 감사 인사(Bohan)

    • 이 발표의 슬라이드나 녹화본을 볼 수 있는 곳이 있는지 질문

    • 이 스레드가 해당 팀에게 다소 박한 평가라는 인상을 받았다는 의견. 이 분야 경험 많은 HN 유저들은 ChatGPT 같은 대규모 서비스를 어떻게 아키텍처적으로 확장했는지, 거의 무제한 자원을 가진 회사가 어떻게 채용하는지에 흥미를 가지고 있다는 설명. "ORM을 쓰면 비효율적인 쿼리가 쉽게 발생하니 조심해야 한다"라는 발표 메시지 자체가, 해당 팀이 이처럼 대규모 인프라 운영에 아직 경험이 많지 않다는 방증이라는 해석

  • 유연성 차원에서 self-hosting postgres는 매력 있지만(슈퍼유저 권한이나 고급 기능 활용 등), 실제로 직접 운영하는 건 신경이 쓰인다는 느낌. 클라우드 제공업체들도 인덱스를 진짜로 드랍하기 전, 쿼리 플래너에서 인덱스 비활성화 기능을 표준적으로 지원하면 좋겠다는 희망. 대기업이라면 스택 커스터마이징을 위해 self-hosting 선택이 충분히 합리적이라는 생각

    • Postgres에서 특정 인덱스를 활용하거나 비활성화하는 다양한 방법이 이미 있고, 클라우드 매니지드 Postgres 인스턴스에서도 쓸 수 있다는 설명. 대표적으로 쿼리 플래너 세팅을 쿼리별로 조정(예: enable_indexscan=off)하거나, where절에 간단한 사칙연산 넣어서 의도적으로 인덱스를 쓰지 않게 하는 방법, 그리고 pg_hintplan 익스텐션(주석문으로 어느 인덱스를 쓰라고 힌트를 줄 수 있음, 참고: https://pg-hint-plan.readthedocs.io/en/latest/…)

    • (Azure Postgres팀 소속임을 밝혀두며) 오픈AI는 self-host가 아니라 Azure의 매니지드 PostgreSQL(Flexible Server)을 사용하고 있음

    • 오픈AI 스피커(Bohan) 본인이 직접 밝혔는데, self-host 환경이 아니라 Azure Database for PostgreSQL을 사용하고 있음. 발표에서 "Azure Postgres"라고 여러 번 언급하긴 했지만, 마이크로소프트가 관리하는 서비스라는 점을 더 명확히 했어야 했다는 점을 사과

    • MySQL이나 MariaDB에는 인덱스를 INVISIBLE이나 IGNORED로 만들어 쿼리 플래너에서 무시하게 하는 DDL이 있는데, 이와 비슷한 기능이 Postgres에는 없는 것이 놀랍다는 의견

    • "Self-hosting postgres 의 장점은 유연함…"이란 원문을 인용만 함

  • 스키마 변경 이벤트(컬럼 추가/삭제 등) 히스토리 기록 기능이 필요하다는 요청에 대해, 이미 EVENT TRIGGER를 활용해 실시간으로 구현 가능하며, 예시로 Aquameta(https://github.com/aquametalabs/aquameta)에서 구현 사례를 참고할 수 있다는 안내

    • 우리도 자체 Postgres 환경에 DDL 변경 이력관리 기능을 구현 중이라는 설명. Postgres 자체가 강력해서 다양한 방식으로 구현 가능하지만, 이력관리와 대규모/중요 DB 운영 기록(log)도 매우 흔한 요구사항이라는 점. 대부분은 직접 뼈저리게 경험해보기 전까지 중요성을 모른다는 주장. DDL 변경뿐 아니라, 주요 운영 정책(예: 가격 모델 변경, SKU/가격 커스텀 등)이 반영될 때도 반드시 "감사 가능성"을 확보해야 한다는 설명. 완전히 릴레이션 모델을 설계하다 보면 실제 앱에선 자주 바뀌는 테이블은 일부이고, 대다수는 거의 변경 없는 "정적(static)" 테이블이라는 점, 이러한 테이블이 바뀔 때는 그 이력을 꼼꼼히 남겨야 과거 데이터 해석 혹은 롤백에 유리하다는 주장

    • 우리(Xata)는 pgroll(https://github.com/xataio/pgroll)과 pgstream(https://github.com/xataio/pgstream) 모두 EVENT TRIGGER로 DDL 변경을 감지하여 스키마 마이그레이션 이력을 남기거나, 스키마 변경 이벤트를 논리적 복제 스트림에 포함시키는 기능을 사용하고 있음. 단, 대부분의 Postgres 기반 DBaaS에서는 EVENT TRIGGER를 슈퍼유저 권한 때문에 일부 제한하고, RDS/Aurora와 Xata는 지원, Supabase도 지원 준비 중이라는 정보

    • Aquameta를 기억해줘서 고맙고, 곧 멋진 새 기능이 나온다는 티징

  • 이 내용(대규모에서의 인덱스 동시 생성, 테이블 리라이트 회피, 트래픽 분산, 트랜잭션 타임아웃, 읽기 레플리카 등)은 사실 오픈AI보다 훨씬 작은 규모 운영에서도 거의 필수(상식)라는 주장. Postgres에 바라는 요구사항도 사실 예전부터 다들 요구해왔던 내용이고, "Next Level"이라고 제목 붙였지만 실제론 싱글 마스터를 필사적으로 유지하며 확장 중인 모습[신규 워크로드 제한있는 상황]에 가깝다는 견해. 대규모 읽기 부하를 무난하게 견디는 게 핵심 포인트인데, 이 자체는 이미 읽기 레플리카와 수평분산의 정석이라는 설명. 인덱스를 disable하는 방법(내부 필드(indisvalid) 조작)도 공식적으로는 제공되지 않는 트릭이고, 이런 식의 시스템 카탈로그 트윅은 위험하다는 경고. 모니터링 뷰로 인덱스 사용 여부를 체크해서 드랍하라는 주장도 완벽한 해결책은 아니며, 어떤 인덱스가 필요/불필요한지 더 명확히 하려면 쿼리 플랜까지 확인해야 신뢰성을 가질 수 있다는 설명

    • TFA(원문 기사)는 오픈AI가 Azure에서 초당 100만 쿼리를 처리하고 있다고 하는데, 이 정도 수준은 실제 클라우드 환경, 특히 네트워크 기반 스토리지 사용 환경에서는 상당히 인상적이라는 해석. 다만 전체적으로 약 40개 읽기 레플리카에 분산된 값이므로 단일 인스턴스당 2.5만 QPS 수준이라 그리 놀랍지는 않다는 의견. 인덱스 사용 여부 논쟁에 대해서는, 최신 통계와 DB 특성만 제대로 파악한다면 인덱스 어느 것을 쓰는 것이 적절한지, 쿼리의 조건/프로젝션이 인덱스의 left-most prefix를 잘 따르는지만 체크하면 충분하다는 설명

    • 오픈AI가 Postgres 샤딩을 하지 않는 이유에 대해 아무런 설명도 없는데, 사실 답답하다고 지적. 유저 단위 샤딩만 해도 훨씬 더 쉽게 문제가 풀릴 것 같은데 왜 싱글 마스터를 고수하는지 의문

  • 물리적 복제를 사용하는 것 같던데, 나는 현재 비용 절감(리전 간 나가는 트래픽 줄이기) 목적으로 논리 복제로 전환 고려 중이라는 고민. Postgres 17 이후로 네이티브 논리복제 기능이 많이 발전한 것 같은데, 실전에서 해볼 만한지 의견이 궁금

  • 다양한 쿼리에 대응하려면 다른 스토리지 엔진(키-값, 검색, 벡터 검색, 캐시 등)도 병행하고 있을텐데, 발표 내용은 오직 Postgres에 집중한 점이 이상하다는 지적. 실제로 내부적으로는 다양한 방식으로 트래픽 분산/부하 분산하는 여러 전략을 펼치고 있을 것 같다는 추정

  • 쓰기 인스턴스만 로컬 고속 SSD를 단 전용 서버에서 직접 운영하고, 읽기는 매니지드 서비스에서만 처리하면 더 좋은 성능이 가능할지 궁금하다는 생각

  • "DB 샤드 좀 해라"는 강한 주장. 유저/조직 단위로 샤딩만 해도 현재 겪는 주요 문제를 간단히 해결할 수 있을 거라는 견해. 복잡한 우회책을 여러 번 시도하는 게 오히려 돌아가는 셈이라는 불만

    • 발표에서는 굳이 샤딩 없이도 단일 마스터 구조만으로도 엄청난 처리량까지 확장 가능하다는 점이 핵심 메시지였으며, 당연히 샤딩도 검토했지만 트레이드오프가 맞지 않아 현재 구조로도 확장이 된다는 경험

    • 오픈AI의 발표자(Bohan) 직접 답변: 워크로드 샤딩이 쉬운 상황은 아니고, 이미 쓰기 부하가 많은 워크로드는 PostgreSQL에서 분리해 샤드로 처리하고 남아있는 것은 거의 읽기 전용이어서 샤딩 도입이 엄청난 노력이 들어간다는 설명. 현재는 Azure Database for PostgreSQL만으로도 충분히 확장성 확보 및 미래 수용 여력까지 있다는 판단. 다만 장기적으로 샤딩을 완전히 배제할 생각은 아니고, 단기 우선순위는 아니라는 메시지

    • 샤딩이 생각만큼 단순하지 않다는 주장. 강력한 DB를 쓰는 이유는 복잡한 데이터 분석/질의가 가능하기 때문이며, 단순 저장/분산만 목적이라면 차라리 여러 NFS 마운트 쓰는 게 더 간단하다는 설명

    • 초당 백만 쿼리처럼 무지막지한 DB에 샤딩을 단순하게 적용하라고 하는 건 쉽지 않은 일이라는 현실감 있는 피드백. 조직 단위가 샤딩 키로 자연스러워 보이긴 해도, 이 정도 스케일부터는 단순한 게 하나도 없다는 의견

    • 위 논지에 적극 동의한다는 반응

  • ORM을 조심해서 쓰라는 발표 언급에 대해, 모든 ORM(특히 다중 DB 호환형 ORM)이 문제라고 생각한다는 본인의 입장. ORM을 쓰다 보면 데이터 패턴을 어플리케이션 코드 수준으로만 생각하게 만들고, 결국 DB마다 제공하는 강력한 기능을 거의 못 쓰게만든다는 주장. 본인은 ORMs를 전혀 쓰지 않고 Postgres 전용 쿼리/기능을 적극적으로 활용, 언어나 편의성보다 DB 파워에 집중하는 것이 훨씬 이득이라는 설명. 결국 좋은 SQL을 직접 작성하는 게 전체 시스템에 행복을 가져다준다는 결론

    • 예전에 DB2에서 psql로 마이그레이션할 때, 다운타임 최소화를 위해 ORM이 큰 도움이 되었던 경험. ORM 덕분에 DB 스위칭이 투명하게 가능했고, 대부분의 로직을 거의 건드리지 않아도 되었으며, 모든 개발자가 직접 쿼리 작성에 익숙하지 않거나 코드에 쿼리가 섞이면 리팩터링/이해가 매우 어려워진다는 주장. 결국 SQL도 라이브러리로 추상화될 것이라는 설명

    • Django ORM을 오랫동안 쓰며 정말 뛰어난 소프트웨어라는 인상을 받았지만, 최근 sqlc를 쓰면서 쿼리를 Go 코드로 바로 바꿔주는 형태가 오히려 ORM과 raw SQL 사이의 이상적인 타협점이라는 생각

    • 진짜 좋은 ORM(예: Entity Framework Core) 경험을 못 해봤을 뿐이라는 입장

  • 제목은 "Scaling PostgreSQL to the Next Level at OpenAI"가 진짜 발표 제목에 맞는 것 같다는 가벼운 피드백