OpenAI: 8억 명의 사용자를 지탱하는 PostgreSQL 대규모 확장 전략
(openai.com)요약:
- OpenAI는 단일 Primary와 약 50개의 Read Replica(Azure Flexible Server)로 수백만 QPS와 8억 명의 사용자를 처리하고 있습니다.
- 쓰기 부하 분산을 위해 샤딩이 가능한 워크로드는 Azure Cosmos DB로 이관하고, 애플리케이션 레벨에서 'Lazy Write' 등을 적용해 쓰기를 최적화했습니다.
- PgBouncer를 도입해 연결 지연 시간을 50ms에서 5ms로 단축했으며, 캐시 미스 스톰을 방지하기 위한 캐시 락(Cache Locking) 메커니즘을 구현했습니다.
- 복잡한 조인 쿼리 제거, 5초 미만의 엄격한 스키마 변경 타임아웃, 트래픽 우선순위에 따른 워크로드 격리 등을 통해 안정성을 확보했습니다.
상세요약:
1. 배경 및 아키텍처 현황
OpenAI의 PostgreSQL 트래픽은 지난 1년 동안 10배 이상 증가하여 현재 8억 명의 사용자와 수백만 QPS(초당 쿼리 수)를 처리하고 있습니다. 놀랍게도 이 규모는 단일 Primary 인스턴스와 전 세계에 분산된 약 50개의 Read Replica 구조로 운영되고 있습니다. 초기 설계의 균열을 막기 위해 OpenAI는 인프라와 애플리케이션 계층 모두에서 대대적인 최적화를 수행했습니다.
2. 주요 병목 해결 및 최적화 전략
-
쓰기(Write) 부하 분산:
- PostgreSQL의 단일 Writer 구조는 확장에 한계가 있고, MVCC(다중 버전 동시성 제어)로 인한 쓰기 증폭 문제가 있습니다.
- 해결책으로 수평적 분할(Sharding)이 가능한 쓰기 집약적 워크로드는 Azure Cosmos DB와 같은 시스템으로 이관했습니다.
- 기존 PostgreSQL에는 새로운 테이블 생성을 금지하고, 애플리케이션 버그 수정 및 Lazy Write(트래픽 스파이크를 평탄화하기 위해 쓰기를 지연 처리)를 도입하여 Primary의 부하를 최소화했습니다.
-
쿼리 최적화 및 ORM 관리:
- 과거 12개의 테이블을 조인하는 쿼리가 장애(SEV)를 유발한 사례가 있어, 복잡한 다중 조인을 피하고 애플리케이션 로직으로 분리했습니다.
- ORM이 생성하는 비효율적인 쿼리를 지속적으로 검토하며,
idle_in_transaction_session_timeout설정을 통해 유휴 쿼리가 Autovacuum을 차단하지 않도록 했습니다.
-
커넥션 풀링 (PgBouncer):
- Azure PostgreSQL의 연결 제한(5,000개)과 연결 폭주를 방지하기 위해 PgBouncer를 프록시 레이어로 배포했습니다.
- 트랜잭션/구문(Statement) 풀링 모드를 사용하여 연결 재사용성을 높였고, 평균 연결 시간을 50ms에서 5ms로 단축했습니다.
-
캐시 미스 방지 (Cache Locking):
- 캐시가 만료되었을 때 수많은 요청이 동시에 DB로 몰리는 'Thundering Herd' 문제를 방지하기 위해 캐시 락(Leasing) 메커니즘을 도입했습니다.
- 특정 키에 대해 캐시 미스가 발생하면, 단 하나의 요청만 DB에 접근 권한(Lock)을 얻어 데이터를 갱신하고, 나머지 요청은 대기하도록 하여 DB 부하를 차단했습니다.
3. 안정성 및 운영 정책
- 단일 실패 지점(SPOF) 완화: Primary 장애 시에도 읽기 요청은 Replica를 통해 처리되도록 하여 장애 등급을 낮췄으며, Primary는 고가용성(HA) 모드로 Hot Standby를 유지해 빠른 페일오버를 보장합니다.
- 워크로드 격리: 'Noisy Neighbor' 문제를 방지하기 위해 트래픽을 중요도(Low/High Priority)에 따라 분리된 인스턴스로 라우팅합니다.
- 엄격한 스키마 관리: 테이블 전체 재작성(Full Table Rewrite)을 유발하는 변경은 금지되며, 스키마 변경 시 5초의 엄격한 타임아웃을 적용해 서비스 지연을 방지합니다.
4. 향후 계획 (The Road Ahead)
현재 구조로도 충분한 확장성을 확보했지만, 향후 더 많은 Read Replica 확장을 위해 Primary가 모든 Replica에 WAL을 전송하는 구조 대신, 중간 Replica가 하위로 WAL을 전달하는 Cascading Replication을 테스트 중입니다. 장기적으로는 PostgreSQL 자체의 샤딩도 고려하고 있습니다.