Postgresの負荷分散について
こんにちは。大阪営業所のこばこばさんです。
丁度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などのミドルウェアに任せたり、リードレプリカのリーダーエンドポイント任せであったり
またはアプリ側での作りこみで実現するなど多種色々ありますが、負荷分散すれば何でも性能が向上するわけではなく
ボトルネックを見極め、適切に構成を見極めなければ性能の向上は難しいと感じました。
以上で今回の検証を終わります。