0

数週間前、大量の同時データベース要求が発生したときに「接続が多すぎる」エラーを防ぐために、データベースアクセス要求のキューイングに関する質問を投稿しました。人々は、ConnectionPoolがその時に私が同意した正しい道であると私に言いました。しかし、接続プールはクライアント側にあるため、すべてのクライアントの接続の合計が最大接続数を超えるのを防ぐことはできないため、ネットワークを介してmysqlサーバーにアクセスするさまざまなクライアントが多数ある場合は特にこれが解決策ではないことにようやく気付きましたmysqlサーバー。

キューまたはプールとして機能するmysqlサーバーにミドルウェアがあるはずだと思いますが、これに精通している人はいますか?ありがとうございました。

私はこの質問が広く尋ねられていることを知っています、私はそれに対する完全な解決策がないかのようにも驚いています。

4

2 に答える 2

1

HAProxyは、目的に応じてTCPレベルのキューイングを実行する必要があります。ただし、TCPよりも意識的なレベルで着信フローを処理するために、中間にアプリケーションサーバーを構築する方がよいでしょうか。これには、サーバーとクライアントの両方の書き換えが必要になる可能性がありますが、何が起こっているかをより細かく制御できる可能性があります。

于 2012-07-19T22:10:08.973 に答える
1

あなたが尋ねることは実際にはかなり複雑な問題です。

まず最初に、データの不整合が許容できるかどうかを判断する必要があります。たとえば、データベースに受信したいいねの数を保存し、12:00:00にこの数を尋ねると、DBの数は次のようになります。 500で、誰かが12:00:01にLIKEを投稿し、12:00:02にもう一度クエリを実行します。正しい番号が501であっても、少しの時間で「501」という答えが出れば、「500」を再度受け取っても大丈夫ですか?

これが許容できる場合(YouTubeの悪名高い「301バグ」)、いくつかのSELECT応答のキャッシュを開始する可能性があります。

それらをミドルウェアにキャッシュすることもできます。つまり、特別なプロセスを継続的に実行し、MySQLへの1つの接続を占有し、キュー内の要求に応答することもできます。サーバーの内部でポート8001のWebサーバーとして実行し、Apache ReverseProxy、HAproxy、pound、またはNginXの場所で外部にプロキシすることができます。

トリッキーな場合でも、特別なUPDATE/DELETEクエリに対して同じことを行うことができます。

プロキシを使用してクエリをシリアル化すると、アプリケーションの速度が大幅に低下する可能性があるため、AJAXを介して非同期で実行されているクエリを最初にキャッシュすることをお勧めします。

あなたには3つの目標があります:

  • ConnectionPoolを解放し、可能な限り負荷を軽くするために、MySQLでクエリを可能な限り高速に実行します(インデックス作成とMySQLキャッシングを調べます)。
  • クエリからすべての情報を抽出するためにアプリケーションをリファクタリングします(たとえば、特定のプロパティを持つ行の数とデータとしてのそれらの行は2つのクエリを使用して取得されることがよくありますが、適切な管理を行うと、1つとSQLNumRows()呼び出しのみが必要になります。 、単一のクエリが一度にすべての情報を返す可能性がある場合、非常に多くの場合、異なる情報を持つ同様のクエリが実行されます。通常、1つのクエリはユーザー/パスワードをチェックし、別のクエリは完全なユーザープロファイルを取得します)。
  • 可能な限り多くの呼び出しを、MySQLにまったくバインドされていないもの(NginX、ミドルウェア)または軽く(キューイングプロセス)に転送します。後者の場合、予測どおりに実行するために既知の数の接続を使用します。

残念ながら、この問題を解決する簡単な「魔法の弾丸」はありません(もちろん、接続数を増やし、マスタースレーブとして実行されている複数のホストでDBを複製することを除いて。実際には魔法の弾丸ではありませんが、設計と実装は簡単です) 。

于 2012-07-19T22:24:27.473 に答える