sql >> データベース >  >> RDS >> PostgreSQL

接続プールを使用したPostgreSQLでの接続のスケーリング

    データベース接続を開くことはコストのかかる操作であり、接続プールを使用してデータベース接続を開いたままにして、再利用できるようにします。これにより、ネットワークセッションを繰り返し開いたり、認証を行ったり、承認を確認したりする必要がなくなります。プーリングは接続をアクティブに保つため、後で接続が要求されたときに、最初から接続を作成するのではなく、アクティブな接続の1つが使用されます。

    接続プール

    接続プーリングは、クエリ要求の前にデータベース接続を処理する最も一般的な方法の1つになっています。通常、データベースへの接続は高速であると考えていますが、特に多数のクライアントが接続している場合はそうではありません。接続プールがない場合、要求は接続に最大35〜50ミリ秒かかりますが、接続プールが使用されている場合は1〜2ミリ秒かかります。したがって、接続プールはデータベース接続を事前に割り当て、新しいクライアントが接続しているときにそれらをリサイクルします

    接続プールの理由

    1. サーバーのクラッシュを回避するため。 PostgreSQLサーバーは、メモリパラメータに応じて、一度に処理するクライアントの数に制限されます。この数を超えると、サーバーがクラッシュすることになります。接続プールでは、クライアントは設定された数の接続を使用します。
    2. クエリ処理を容易にします。通常、データベース要求は先入れ先出しの基準でシリアル方式で実行されます。クライアントの大規模なセットでは、これはこのプロセスを達成するために何年もかかります。したがって、アプローチは、一度に実行するのではなく、同時に実行できるパイプライン要求を使用して単一の接続を確立することです。
    3. セキュリティを向上させます。多くの場合、接続には、SSLが確立され、パスワードがチェックされ、構成情報が共有されるまでに平均25〜35ミリ秒かかるハンドシェイクが含まれます。接続されているユーザーごとにこのすべての作業を行うと、メモリが大量に使用されます。ただし、接続プールを使用すると、接続数が減るため、メモリを節約できます。

    接続プールの種類

    接続プールには基本的に2つのタイプがありますが、永続接続と呼ばれる接続プール戦略のように機能する3番目のタイプの回避策があります。

    永続的な接続プール

    このアプローチは、初期接続が開始されたときからアクティブな状態を維持することを目的としています。接続プール機能を完全に保持しているわけではありませんが、継続的な接続を提供するには十分です。オーバーヘッドが25〜50ミリ秒の範囲である可能性があるクライアント接続の小さなセットに非常に役立ちます。このアプローチの制限は、データベースへの接続数に制限され、通常はサーバーへのエントリごとに1つの接続に制限されることです。

    フレームワーク接続プール

    フレームワーク接続プーリングはアプリケーションレベルで発生します。これにより、サーバースクリプトが開始されるたびに、後で到着するクエリ要求を処理するための接続プールが確立されます。

    スタンドアロン接続プール

    データベースへの接続ごとに、クエリ要求に対応するために5〜10MBのオーバーヘッドメモリが使用されます。これは、多数の接続にはあまり適していません。フレームワーク接続プールの使用は、メモリサイズの使用量が多くなる可能性があるため、この接続数によって制限される可能性があります。したがって、Postgresセッション、ステートメント、およびトランザクションに従って構成されたスタンドアロン接続プールを使用することを選択します。このアプローチに関連する主な利点は、接続ごとに約2kbの最小オーバーヘッドコストです。

    接続プールクラスを作成するときは、データベースのパフォーマンスを向上させるために、次の要素を満たす必要があります。

    1. 接続を事前に割り当てます
    2. 利用可能な接続を監視する
    3. 新しい接続を割り当てる
    4. 接続が利用可能になるのを待ちます
    5. 接続を閉じる
    今日のホワイトペーパーをダウンロードするClusterControlを使用したPostgreSQLの管理と自動化PostgreSQLの導入、監視、管理、スケーリングを行うために知っておくべきことについて学ぶホワイトペーパーをダウンロードする

    接続の事前割り当て

    事前に接続を増やすと、アプリケーションが開始された時点でのリクエスト処理が容易になります。たとえば、サーバーがJavaで開発されている場合、ベクターを使用して、以下のコードを使用して使用可能なアイドル接続を保存できます。

    availableConnections = new Vector(connections); 
    busyConnections = new Vector();
    for(int i=0; i<connections; i++) {
    availableConnections.addElement(makeNewConnection()); 
    }

    利用可能な接続の監視

    クラスは、ビジー接続のリストでアイドル状態の接続をチェックして、それを返すことができる必要があります。これは基本的に、使用されていない接続を再利用したり、接続を閉じたりするために行われます。接続がタイムアウトすることがあるため、接続を返すときに、接続がまだ開いているかどうかを確認することが非常に重要です。そうでない場合は、この接続を破棄してプロセスを繰り返す必要があります。接続が破棄されると、制限に達したときに新しい接続を処理するために使用できるスロットが開かれます。これは

    で達成できます
    public synchronized Connection getConnection() throws SQLException {
    if (!availableConnections.isEmpty()) { Connection existingConnection =
    (Connection)availableConnections.lastElement(); int lastIndex = availableConnections.size() - 1; availableConnections.removeElementAt(lastIndex); if (existingConnection.isClosed()) {
    notifyAll(); // Freed up a spot for anybody waiting.
    return(getConnection()); // Repeat process. } else {
    busyConnections.addElement(existingConnection);
    return(existingConnection); }
    } }

    新しい接続の割り当て

    使用可能なアイドル状態がなく、接続制限にほぼ達している場合は、バックグラウンドスレッドを開始して新しい接続を割り当てることができるはずです。

    if ((totalConnections() < maxConnections) && !connectionPending) { // Pending = connecting in bg
    makeBackgroundConnection(); }
    try {
    wait(); // Give up lock and suspend self.
    } catch(InterruptedException ie) {} return(getConnection()); // Try again.

    新しい接続を待っています

    アイドル状態の接続がなく、接続制限に達した場合、構成は、継続的にプールすることなく、新しい接続が使用可能になるのを待機できる必要があります。これは、スレッド同期ロックを提供し、通知が提供されるまでスレッドを一時停止するwaitメソッドを使用して行うことができます。

    try {
         wait();
    } catch(InterruptedException ie) {} 
    return(getConnection());

    優れたアプリケーション倫理のために、クライアントは接続をリアルタイムで待つべきではありません。接続がない場合は、以下のコードで例外をスローします。

    throw new SQLException("Connection limit reached");

    接続を閉じる

    接続がガベージコレクションされる場合は、明示的に行うのではなく、接続を閉じる必要があります。ただし、接続を閉じるための明示的なアプローチが必要な場合は、次を使用できます。

    public synchronized void closeAllConnections() {
    // The closeConnections method loops down Vector, calling // close and ignoring any exceptions thrown. closeConnections(availableConnections); availableConnections = new Vector(); closeConnections(busyConnections);
    busyConnections = new Vector();
    }

    結論

    PostgreSQLの接続プールは、データベースへの接続に必要なリソースの数を減らし、データベースへの接続速度を向上させるのに役立ちます。これは、DBへの接続をプールし、これらの接続を維持し、その結果、開く必要のある接続の数を減らすことによって実現されます。


    1. SQLServerのAlwaysOn機能の使用方法

    2. MySQLサンプルデータベース

    3. パフォーマンスの神話:切り捨てられたカントはロールバックされます

    4. mysqlのテーブルから重複する行を削除する方法