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

AppEngineからのGoogleCloudSQLの接続制限と、DB接続を最適に再利用する方法を教えてください。

    簡単な答え:クエリが遅すぎる可能性があり、mysqlサーバーには送信しようとしているすべてのリクエストを処理するのに十分なスレッドがありません。

    長い答え:

    背景として、CloudSQLにはここに関連する2つの制限があります。

    • 接続:これらは、コードの「conn」オブジェクトに対応します。サーバーには対応するデータ構造があります。これらのオブジェクトが多すぎると(現在1000に構成されている)、最も最近使用されていないオブジェクトは自動的に閉じられます。接続が閉じられると、次にその接続を使用しようとしたときに、不明な接続エラー(ApplicationError:1007)が発生します。
    • 同時リクエスト:これらはサーバーで実行されているクエリです。実行中の各クエリはサーバー内のスレッドを拘束するため、100の制限があります。同時リクエストが多すぎると、後続のリクエストは、発生するエラー(ApplicationError:1033)で拒否されます。

    接続制限が影響しているようには聞こえませんが、念のために言及したいと思います。

    同時リクエストに関しては、制限を増やすと役立つ場合がありますが、通常は問題が悪化します。過去に見た2つのケースがあります:

    • デッドロック:実行時間の長いクエリがデータベースの重要な行をロックしています。以降のすべてのクエリは、そのロックでブロックされます。アプリはこれらのクエリでタイムアウトしますが、サーバー上で実行を続け、デッドロックタイムアウト トリガー。
    • 遅いクエリ:各クエリは本当に、本当に遅いです。これは通常、クエリで一時ファイルの並べ替えが必要な場合に発生します。アプリケーションはタイムアウトになり、クエリの最初の試行がまだ実行されている間にクエリを再試行し、同時リクエストの制限に対してカウントします。平均クエリ時間を見つけることができれば、mysqlインスタンスがサポートできるQPSの推定値を取得できます(たとえば、クエリあたり5ミリ秒はスレッドごとに200 QPSを意味します。100スレッドがあるため、20,000QPSを実行できます。50ミリ秒クエリあたりは2000QPSを意味します。)

    EXPLAIN を使用する必要があります および SHOW ENGINE INNODB STATUS 2つの問題のどちらが起こっているかを確認します。

    もちろん、インスタンスで大量のトラフィックを駆動しているだけで、スレッドが不足している可能性もあります。その場合、とにかくインスタンスのCPUを最大化する可能性があるため、スレッドを追加しても効果はありません。



    1. 自動インクリメントの開始番号を変更しますか?

    2. すべてのUTF8文字を最も標準的な形式に正規化する

    3. プリペアドステートメントでワイルドカードのように使用する

    4. 日付と時刻のデータのバケット化