Webアプリケーション用に複数のPostgreSQLサーバーがあります。通常、ホットスタンバイモードの1つのマスターと複数のスレーブ(非同期ストリーミングレプリケーション)。
接続プールにPGBouncerを使用します。ローカルホストのデータベースに接続する各PGサーバー(ポート6432)に1つのインスタンスがインストールされています。トランザクションプールモードを使用します。
スレーブでの読み取り専用接続の負荷を分散するために、HAProxy(v1.5)を次のような設定で使用します。
listen pgsql_pool 0.0.0.0:10001
mode tcp
option pgsql-check user ha
balance roundrobin
server master 10.0.0.1:6432 check backup
server slave1 10.0.0.2:6432 check
server slave2 10.0.0.3:6432 check
server slave3 10.0.0.4:6432 check
したがって、私のWebアプリケーションはhaproxy(ポート10001)に接続します。これにより、各PGスレーブで構成された複数のpgbouncerで接続の負荷を分散します。
これが私の現在のアーキテクチャの表現グラフです:
これはこのように非常にうまく機能しますが、一部はこれをまったく異なる方法で実装していることに気づきます:Webアプリケーションは、複数のPGサーバーで負荷分散するHAproxyに接続する単一のPGBouncerインスタンスに接続します。
最善のアプローチは何ですか?最初のもの(私の現在のもの)または2番目のもの?あるソリューションが他のソリューションよりも優れている点はありますか?
ありがとう
HAProxy-> PGBouncer-> PGServer approchの既存の構成の方が優れています。そして、それはうまくいきます。その理由は次のとおりです。HAProxyが接続を別のサーバーにリダイレクトします。これにより、データベース接続でMACアドレスが変更されます。したがって、PGBouncerがHAProxyを超えている場合、MACアドレスの変更が原因でプール内の接続が無効になるたびに。
pgbouncerは、postgresサーバーとのプール内の接続を維持します。 TCP接続確立時間は、大容量環境では重要です。
多数のDB要求を行うクライアントは、要求ごとにリモートPGBouncerとの接続をセットアップする必要があります。これは、PgBouncerをローカルで実行する(アプリケーションがpgbouncerにローカルで接続する)よりもコストがかかり、pgBouncerはリモートPGサーバーとの接続のプールを維持します。
したがって、IMO、PGBouncer-> HAProxy-> PGServerは、HAPGxy-> PGBouncer-> PGServerよりも優れているようです。特に、PGBouncerがクライアントアプリケーションに対してローカルである場合はそうです。
Donatelloの答えに同意しないといけません。
アプリケーションがローカルプールを使用してDB接続を管理していない場合、DBにクエリを実行する必要があるたびに新しい接続が作成されます。これはPgBouncerを使用した場合とまったく同じように行われるため、PgBouncerを使用することで非常に優れた改善が得られます。
PgBouncerがPostgreSQL接続をプールして管理している場合、接続がDBに直接開かれる場合と比較して、アプリが接続を開くのに費やす時間は大幅に減少します。これは、接続が要求されるたびに、PGが資格情報およびすべてをチェックおよび検証するのが非常に遅いためです。
したがって、App-> HAProxy-> [PgBouncer-> PostgreSQL]のアプローチは、PgBouncerがPGへの接続時間を節約するため、より優れています。プーリングモードも考慮する必要があります。アプリの動作に注意する必要があります。それは主にトランザクションですか?それとも、同時実行性の高い一連の小さなSQL文を実行するのですか?これらのパラメーターはすべて、パフォーマンスに影響を与えます。