Odyssey:大規模スケール時のPostgreSQLを「ボトルネック」から救う究極の解決策

Database tutorial - IT technology blog
Database tutorial - IT technology blog

背景:深夜2時にPgBouncerが限界を迎えたとき

午前2時、Slackのアラートが鳴り止まない。モニタリング画面には「“PostgreSQL: Too many connections」という絶望的な文字。PgBouncerを細かくチューニングしていたにもかかわらず、マイクロサービスからのトラフィックが秒間5,000接続に急増したことで、システムは深刻なボトルネックに陥りました。

問題はPgBouncerのシングルスレッド(single-threaded)アーキテクチャにあります。64コアのサーバーであっても、PgBouncerは1つのコアしか使い切れず、残りの63コアを無駄にしてしまいます。これが、私がOdysseyに切り替えた理由です。これはYandexが開発したモダンなConnection Poolerで、超大規模な負荷がかかるシステム向けにマルチスレッド(multi-threaded)のパワーを最大限に引き出すよう設計されています。

PostgreSQLの接続管理は常に難題です。MySQLやMongoDBを使ったことがあれば、Postgresが接続ごとに新しいプロセスを生成する仕組みがいかにリソースを消費するかを実感しているでしょう。Odysseyは、この問題をエンタープライズ規模で根本から解決するために誕生しました。

なぜOdysseyはPgBouncerより優れているのか?

数十億件のレコードを処理するシステムでの実戦投入を通じて、Odysseyには4つの大きなメリットがあると感じています:

  • マルチスレッド性能: CPUコア数に応じてスケールできるため、PgBouncerと比較してスループットを2〜3倍に向上させることが可能です。
  • インテリジェントなTransaction Pooling: アプリケーションとデータベース間の接続確立におけるレイテンシを大幅に削減します。
  • 詳細なリソース管理: ユーザーやデータベースごとに個別のプールサイズを制限できるため、特定のサービスが接続を独占して他のサービスを阻害するのを防げます。
  • 最適化されたキュー(Queue)メカニズム: データベースが高負荷の際、Odysseyは接続を即座に切断するのではなくキューに保持するため、システムの安定性が向上します。

Ubuntu/DebianへのOdysseyのインストール

最高のパフォーマンスを得るために、ソースコードから直接ビルドすることをお勧めします。これにより、サーバーのCPUアーキテクチャに最適化されたバイナリが生成されます。

1. ビルド環境の準備

sudo apt-get update
sudo apt-get install -y build-essential cmake git libssl-dev libpcre3-dev postgresql-common postgresql-client

2. ソースコードのコンパイル

git clone https://github.com/yandex/odyssey.git
cd odyssey
mkdir build && cd build
cmake ..
make

make コマンドが完了すると、実行ファイルは sources ディレクトリに作成されます。これをシステムディレクトリに移動しましょう:

sudo cp sources/odyssey /usr/local/bin/

Odysseyの設定:プロダクション環境での実践

Odysseyの設定ファイルはプログラミング言語に近い形式を採用しており、非常に明快です。以下は、高頻度のクエリが発生するシステムで私がよく使用する設定サンプルです。

# CPUコア数に合わせてワーカー数を宣言
workers 8

log_file "/var/log/odyssey.log"
log_debug no

listen {
    host "0.0.0.0"
    port 6432
    backlog 4096 # バーストトラフィックに耐えられるようバックログを増やす
}

storage "postgres_server" {
    type "remote"
    host "10.0.0.5" # DBサーバーのIPアドレス
    port 5432
}

database "prod_db" {
    user "web_app" {
        authentication "cleartext"
        password "secret_pass"
        
        storage "postgres_server"
        storage_db "prod_db"
        storage_user "web_app"
        storage_password "secret_pass"

        # トランザクションモードにより接続を高速に再利用
        pool "transaction"
        pool_size 100
        pool_timeout 0
        pool_ttl 60
    }
}

特に注意すべきパラメータ:

  • workers: CPUコア数に設定します。リソース의競合(コンテキストスイッチ)を避けるため、過剰に設定しないでください。
  • pool “transaction”: Webバックエンドに最適なモードです。SQL文の実行が完了すると、接続は即座にプールに返却されます。
  • backlog: デフォルト値は通常低いため、数千のリクエストが同時に押し寄せる場合は4096まで引き上げてください。

監視と運用

以下のシンプルなコマンドでOdysseyを起動します:

odyssey /etc/odyssey/odyssey.conf

システムの健全性を確認するには、Odysseyの仮想データベース console にアクセスします。ここではパフォーマンスに関するリアルタイムの統計情報を確認できます。

psql -h localhost -p 6432 -d console -c "SHOW STATS"

特に waiting_clients カラムに注目してください。この数値が上昇し続けている場合、pool_size が小さすぎるか、バックエンドのデータベースのクエリ処理が遅すぎることを示しています。

重要な注意点:トランザクションモードの弱点

よくある間違いは、Prepared StatementsTemporary Tables を使用するアプリケーションで pool "transaction" を使用することです。Odysseyは接続を頻繁に入れ替えるため、次のコマンドがPrepared Statementが初期化されていない別の接続で実行され、ロジックエラーを引き起こす可能性があります。これらの機能が必須な場合は、pool "session" を選択してください。

おわりに

Odysseyは単なる代替ツールではなく、PostgreSQLのパフォーマンスにおける飛躍的な進化です。マルチスレッドアーキテクチャを活用することで、大規模なトラフィックに対しても、より粘り強く強固なシステムを構築できます。

この実戦的な共有が、皆様のシステム最適化に役立つことを願っています。設定で困ったことがあれば、ぜひコメント欄で質問してください!

Share: