コンピューターシステム株式会社

技術BLOG

Postgresの負荷分散について

2021/10/29 大阪担当

こんにちは。大阪営業所のこばこばさんです。

丁度AWSのAmazon Auroraを調査しており、RDS ProxyやAuroraクラスターに触れる機会が多かったので

負荷分散技術について検証してみようと思い立ちました。

今回はPgPoolを使用してPostgresqlの負荷分散に挑戦したいと思います。

まずPgPoolについて紹介します。

Pgpool-IIは、PostgreSQLサーバとPostgreSQLデータベースクライアントの間に

位置するプロキシソフトウェアとなり、主に以下のような機能を提供します。

・コネクションプーリング

・負荷分散

・自動フェイルオーバ

・オンラインリカバリ

・レプリケーション

・限度を超えた接続の制限

・Watchdog

・インメモリキャッシュ

上記機能のうち、今回は負荷分散に着目して紹介したいと思います。

まず負荷分散機能を検証するために必要な構成として、事前に以下を準備しました。

※検証ではDBサーバーをlocalhost内で構築していますが、localhostを別サーバー/別DBと見立ててください。

 上記構成のDBサーバーに対して、以下手順に沿ってPgPoolを構築しました。

・yumからインストール

 yum install https://www.pgpool.net/yum/rpms/4.2/redhat/rhel-7-x86_64/pgpool-II-pg12-4.2.5-1pgdg.rhel7.x86_64.rpm

 ※OSのバージョンやpostgresqlのバージョン別に対応しているモジュールも変わるので、適宜環境に合わせてモジュールを探してください。

・インストール確認

 rpm -qa | grep pgpool

 上記のようにpgpoolが出力されればインストール出来ています。

 次に、PgPoolのサービスを起動します。

・サービス動作確認

 systemctl status pgpool

 インストールしただけなので、「Active: inactive (dead)」となっており、起動していません。

・サービス起動

 systemctl start pgpool

 上記コマンドでPgPoolを起動すると、ステータスが下記のように

 「Active: active (running)」となります。

 これでPgPoolが動作する環境となりましたが、何も設定していないので

 ここから設定を行い、PgPoolを経由してPostgreSQLへ接続できる環境にしていきます。

・pgpool.confの接続設定

 段階を踏んでまずはPgPool越しにDBに接続するためだけの設定を行います。

 vi /etc/pgpool-II/pgpool.conf

 上記コマンドで設定項目は以下の通り編集を行いました。

 backend_hostname0 = 'localhost'

 backend_port0 = 5432

・接続確認

 PSQLコマンドでlocalhost:9999に対して接続します。指定Databaseはテスト用に作成したtest_dbを指定しています。

 psql -h localhost -p 9999 -U postgres test_db

 ※PgPoolはデフォルトでポート9999で待ち受けしているので、9999に向けて接続します。

 このように9999ポートに向けた接続でpsqlがつながったので、PgPool越しにPostgresに繋がったことがわかります。

 ※PostgrSQLはデフォルトポートの5432で構築しています。

 ここから性能測定を行っていきます、性能測定はpgbenchを使用し、TPSを測定します。

 ※TPS=Transactions Per Second(コンピュータシステムの処理性能の指標の一つで、トランザクション処理を毎秒何件実行できるかを表したもの。)

・性能測定1 PgPoolを介さず、直接postgresにつないで性能測定

 pgbench -c 5 -t 100 -U postgres -h localhost -p 5432 test_db

 結果は

 tps = 901.851501 (including connections establishing)

 tps = 922.996267 (excluding connections establishing)

 となっており、秒間900程度の処理を行っているのが分ります。

 ※includingの数値はPostgreSQLに対する接続を確立する時間を含んでいるので、秒間当たりの処理数はexcludingより下がります。

・性能測定2 PgPoolを介するが負荷分散設定が無い場合の性能測定

 pgbench -c 5 -t 100 -U postgres -h localhost -p 9999 test_db

 結果は

 tps = 650.522435 (including connections establishing)

 tps = 665.081113 (excluding connections establishing)

 となっており、秒間650程度の処理となり、直接postgresにつないだ場合より性能が落ちているのがわかります。

 これはPgPoolを経由しているので、余計な処理がかかっているためと推測されます。

 上記、測定値と負荷分散を行った場合の測定値を見比べたいと思います。

・性能測定3 PgPoolを介して負荷分散設定を行った場合の性能測定

 vi /etc/pgpool-II/pgpool.conf

 上記コマンドで設定項目は以下の通り編集を行いました。

 backend_hostname1 = 'localhost'

 backend_port1 = 5432

 上記設定を行ったのち、PgPoolを再起動し性能測定を行いました。

 pgbench -c 5 -t 100 -U postgres -h localhost -p 9999 test_db

 結果は

 tps = 755.886466 (including connections establishing)

 tps = 758.674686 (excluding connections establishing)

 となっており、秒間750程度の処理となり、直接postgresにつないだ場合より性能が落ちますが

 若干ですが負荷分散設定が無い場合より、性能向上しています。

・検証の結果

 上記構成で負荷分散の検証を行った所感として

 負荷分散の実現自体はPgPoolなどのミドルウェアに任せたり、リードレプリカのリーダーエンドポイント任せであったり

 またはアプリ側での作りこみで実現するなど多種色々ありますが、負荷分散すれば何でも性能が向上するわけではなく

 ボトルネックを見極め、適切に構成を見極めなければ性能の向上は難しいと感じました。

 以上で今回の検証を終わります。