PgBouncer를 4배 처리량으로 확장한 방법

원제: We scaled PgBouncer to 4x throughput

왜 중요한가

단일 스레드 한계를 가진 PgBouncer를 멀티코어로 수평 확장하는 실용적 아키텍처로, 관리형 Postgres 서비스의 성능 한계를 대폭 끌어올릴 수 있음을 실증했다.

ClickHouse는 자사의 관리형 Postgres 서비스에서 PgBouncer의 처리량을 최대 4배로 확장하는 데 성공했다고 2026년 7월 1일 발표했다. 단일 스레드 구조의 PgBouncer를 복수 프로세스로 구성하고, so_reuseport를 활용해 16vCPU 환경에서 모든 코어를 병렬 활용하는 방식으로 달성했다.

PgBouncer는 단일 스레드 구조로 설계되어 있어, 16vCPU 환경에서도 1개의 CPU 코어만 사용하며 나머지 15개는 유휴 상태로 남는다. ClickHouse Managed Postgres 팀은 이 병목 현상을 해결하기 위해, 사용 가능한 코어 수에 비례하여 PgBouncer 프로세스 집합(fleet)을 운영하는 방식을 도입했다.

핵심 기술은 Linux 커널의 so_reuseport 옵션 활용이다. 각 프로세스가 동일한 포트를 바인딩하면 커널이 들어오는 연결을 프로세스 전체에 부하 분산시키며, 클라이언트 측에서는 단일 엔드포인트처럼 보인다.

이 구성에서 발생하는 주요 문제는 쿼리 취소(query cancellation)이다. Postgres의 취소 요청은 새로운 연결로 cancel key를 전달하는데, so_reuseport 환경에서는 해당 연결이 원래 세션을 보유하지 않은 다른 프로세스에 전달될 수 있다. ClickHouse는 프로세스 간 '피어링(peering)' 메커니즘을 도입하여, 잘못된 프로세스에 도착한 취소 요청을 실제 세션을 보유한 프로세스로 전달하도록 구현했다.

또한 커넥션 예산은 fleet 전체에 균등 분배된다. max_client_conn과 max_db_connections를 프로세스 수로 나누어 Postgres 측의 과부하를 방지한다. 풀링은 트랜잭션 모드로 동작하며, 트랜잭션 완료 시 서버 연결이 즉시 풀로 반환된다.

실측 결과는 AWS EC2 c7i.4xlarge(16vCPU) 인스턴스에서 pgbench를 이용한 읽기 전용 트랜잭션 풀 모드 벤치마크로 검증되었으며, 단일 프로세스 대비 fleet 구성(16 프로세스)에서 처리량이 4배 향상되었다.

출처

clickhouse.com — 원문 읽기 →