PostgreSQL環境でPgBouncer を高可用性構成で実装する際の考え方を解説します。バックエンドのPostgreSQL自体のHA構成は考慮せず、あくまでPgBouncer側のみを高可用性化する方法を簡単な構成例とあわせて解説します。
なぜPostgreSQLにはPgBouncerが重要なのか
PostgreSQLの接続コストの高さ
PostgreSQLは、クライアントごとに新しいプロセスを作成する構造を採用しています。このため、多数の接続が発生すると、その分だけプロセスも増え、CPUやメモリを圧迫しやすくなります。また、接続を確立すること自体にもコストがかかります。
アイドル接続がリソースを消費
PostgreSQLはクライアントがアイドル状態のままでも、バックエンドプロセスを持ち続けます。これはユーザー数が多い場合にメモリ・CPUなどのリソースを無駄にする原因となります。
PgBouncerによる解決策
PgBouncerは、PostgreSQLのクライアント接続をプールし、複数の接続を最低限に抑えることが可能な軟体です。PgBouncerを使用することで、接続コストやリソース消費を削減できます。
PgBouncerのHA構成の考え方
今回のシナリオでは、**バックエンドのPostgreSQL自体は単体運用またはレプリケーション構成が実現されていると仮定し、**PgBouncerのみを高可用構成にする方法を解説します。目的は、PgBouncerの障害時に別のインスタンスに切り替えることで、クライアントの接続を続行させることにあります。
Docker Composeを使った簡単なHA構成例
下記は、Docker Composeで複数のPgBouncerインスタンスを起動し、障害時に別インスタンスに自動切り替えを実現する構成例です。
docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: yourpassword
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ['CMD', 'pg_isready', '-U', 'postgres']
interval: 30s
timeout: 10s
retries: 5
pgbouncer:
image: edoburu/pgbouncer:latest
environment:
DB_USER: postgres
DB_PASSWORD: yourpassword
DB_HOST: postgres
POOL_MODE: transaction
ports:
- "6432:6432"
deploy:
replicas: 2
depends_on:
postgres:
condition: service_healthy
healthcheck:
test: ['CMD', 'pg_isready', '-p', '6432']
interval: 30s
timeout: 10s
retries: 5
volumes:
pg_data:
構成のポイント
複数のPgBouncerインスタンス
deploy.replicas
により、同じ設定で複数のPgBouncerを起動します。- Dockerのサービスディスカバリ機能により、障害が発生した際にも別のインスタンスに接続を切り替えることが可能になります。
ヘルスチェック
- PostgreSQLとPgBouncerの両方にヘルスチェックを実装し、状態監視を行います。
プールモード
- PgBouncerのプールモードに
transaction
を選択し、クライアントごとに接続が固定されることを避けます。これにより、障害の影響を最小限に抑えることができます。
- PgBouncerのプールモードに
Docker ComposeをつかったPgBouncerの高可用構成を紹介しました、Docker Composeのサービスディスカバリを使用することでシンプルで軽量な実装が可能です。 重要なシステムでは、HAProxyなどの搭載も検討すると良いでしょう。