-1

100 を超えるサーバーを持つ Java アプリを使用しています。現在、各サーバーはリレーショナル データベースの 7 つのデータベース スキーマへの接続を開きます (ログ、これ、あれ、その他)。すべてのスキーマは同じ DB クラスターに接続しますが、事実上すべて 1 つのデータベース インスタンスです。

サーバー管理の接続プールは、インスタンスごとに各データベース スキーマで少数の接続 (1 ~ 5) を開き、冗長プールではそれを 2 倍にします。したがって、各サーバーは最低 30 のデータベース接続を開き、サーバーごとに最大で数百まで増加する可能性があり、ここでも 100 を超えるサーバーがあります。

全体として、使用されるデータベース接続の最小数は 3000 であり、これはばかげたものになる可能性があります。

明らかに、これは単純に間違っています。データベース クラスタは、X 件の同時リクエストのみを効率的に処理できます。リクエスト数が X を超えると、不要な競合が発生し、全体の速度が低下します。(X は不明ですが、最小同時接続数 3000 よりもかなり小さいです)。

次の戦略を実装して、使用される合計接続数を減らしたい:

  1. 1 つのスキーマのみに接続し (Application-X)、プールごとに最大 6 つの接続があります。
  2. 必要なスキーマに切り替えるプールの上にレイヤーを記述します。getConnection(forSchema) 関数は、ターゲット スキーマのパラメーター (例: ロギング) を受け取り、任意のスキーマを最後に指す可能性がある接続を取得し、スキーマ切り替え SQL ステートメントを発行します (search_path を 'target_schema' に設定します)。

このアプローチが正しいか間違っているかについてコメントしないでください。「場合による」を考慮する必要があるため、そのようなコメントは付加価値になりません。

私の質問は、これを既に実行している DB プールの実装があるかどうかです-接続のセットを 1 つ持つことができ、自動的に適切なスキーマに配置できます。または、さらに良いことに、プールされた接続がターゲットスキーマで使用可能かどうかを追跡します。先に進んでスキーマを切り替えることを決定します (DB ラウンドトリップを節約します)。

また、別の方法で解決した場合は、同様の問題(実際の経験)を持っている他の人からも聞きたいです。

4

1 に答える 1

2

Web アプリケーションとデータベース間のデータベース接続数を安定させる最善の方法は、Web アプリケーションの前にリバース プロキシを配置することです。

これが機能する理由は次のとおりです。

Web 要求の遅い部分は、データをクライアントに返す場合があります。大量のデータがある場合、またはユーザーの接続が低速の場合、Web サーバーに対して接続が開いたままになる可能性があり、そこでデータがクライアントにゆっくりと滴り落ちます。その間、アプリケーション サーバーはバックエンド サーバーへのデータベース接続を開いたままにします。データベース接続は、トランザクションのごく一部にしか必要としない場合がありますが、クライアントがアプリケーション サーバーから切断されるまでは接続されたままになります。

ここで、アプリ サーバーの前にリバース プロキシを追加するとどうなるかを考えてみましょう。アプリ サーバーが応答を準備すると、その前にあるリバース プロキシにすばやく応答し、その背後にあるデータベース接続を解放できます。リバース プロキシは、関連するデータベース接続を拘束したままにすることなく、uses へのゆっくりとした応答を処理できます。

このアーキテクチャの変更を行う前は、多くのトラフィック スパイクが発生し、デス スパイラルが発生していました。データベース ハンドルの使用量が急増し、そこから下り坂になっていました。

変更後、必要なデータベース ハンドルの数ははるかに少なくなり、はるかに安定しました。

リバース プロキシがまだアーキテクチャに組み込まれていない場合は、必要なデータベース接続の数を制御するための最初のステップとして使用することをお勧めします。

于 2013-09-09T19:37:08.343 に答える