PgBouncerをマルチプロセス化でスループット4倍に

原題: We scaled PgBouncer to 4x throughput

なぜ重要か

マルチプロセスPgBouncer構成はPostgres管理サービス全体のスケーラビリティ課題への実践的解法として業界注目度が高い。

ClickHouseは、同社のManaged Postgresサービスにおいて、PgBouncerをシングルプロセスからマルチプロセス構成に変更することでスループットを最大4倍に向上させたと発表した。AWS EC2の16vCPUインスタンス(c7i.4xlarge)を用いた実測で、16プロセス構成がシングルプロセス比で約4倍のスループットを達成した。

ClickHouseは2026年7月1日、同社のManaged Postgresサービスにおいて、PgBouncerのスケーリング手法を公式ブログで詳細に公開した。

PgBouncerはシングルスレッドで動作するため、1プロセスにつき1CPUコアしか使用しない。16vCPUマシンでも1コアだけがコネクションプーリングを担い、残りの15コアが遊休状態になる構造上の課題があった。

ClickHouseが採用した解決策は、利用可能なCPUコア数に比例したPgBouncerプロセス群(フリート)の運用だ。各プロセスは`SO_REUSEPORT`オプションを有効にした同一ポートにバインドし、カーネルが受信接続を各プロセスに負荷分散する。クライアントからは単一のエンドポイントに見えるため、構成の変更を意識する必要はない。この手法はPgBouncer公式ドキュメントでも複数コアを活用する方法として紹介されている。

ただし、`SO_REUSEPORT`を使用する際にはクエリキャンセルの問題が発生する。Postgresのキャンセルリクエストはキャンセルキーを持つ別の新規接続で届くため、カーネルがセッションを保持しているプロセスとは異なるプロセスにその接続を割り当てる場合がある。ClickHouseはプロセス間の「ピアリング」機能でこれを解決した。各プロセスがお互いを認識しており、誤ったプロセスに届いたキャンセルリクエストを実際にセッションを持つプロセスへ転送する仕組みを実装した。

コネクション管理については、トランザクションモードでプーリングを行い、`max_client_conn`と`max_db_connections`をプロセス数で分割することで、フリート全体としてPostgresへのコネクション過剰割り当てを防止している。

実測では、AWS EC2のc7i.4xlarge(16vCPU)をプーラー用、別ボックスをPostgres用、さらに別ボックスをpgbenchによる負荷生成用として使用した。セレクトオンリー・トランザクションプールモードで比較したところ、16プロセス構成はシングルプロセス構成に対してスループットが約4倍に向上することが確認された。

出典

clickhouse.com — 元記事を読む →