ユーザー数の増加、日々のアクティビティとピーク値の急増に伴い、データベース処理パフォーマンスは大きな課題に直面しています。ピーク値が 100,000 以上である実際のプラットフォームのデータベース最適化計画を共有しましょう。みんなで話し合い、お互いに学び合い、改善していきましょう!
ケース: ゲーム プラットフォーム
1. 高い同時実行性を解決します
クライアント接続の数がピークに達した場合、サーバーによる接続の維持と処理については、当面ここでは説明しません。複数の書き込みリクエストがデータベースに送信される場合、特に 1 日に数千万件のデータを保存する一部の式は、この時点で挿入する必要があります。実験後にデータを同期的に書き込む従来の方法は明らかに推奨されません。非同期挿入によって大幅に改善されましたが、同時に、データ読み取りのリアルタイム パフォーマンスをある程度犠牲にする必要があります。
多くの非同期方法があります。現在の方法は、ジョブを通じて一定の間隔 (5 分、10 分など) で一時テーブルから実際のテーブルにデータを転送することです。
1. オリジナルのテーブルAがあり、これは実際に読み取り時に使用されるテーブルでもあります。
2. データ転送処理用に元のテーブル A と同じ構造の B と C を作成します。同期プロセスは C->B->A です。
3. データを同期するジョブ Job1 と、Job1 の実行ステータスを記録するテーブルを確立します。同期中に最も重要なことは、B のデータが現在 A に同期されている場合は、Job1 の現在のステータスを確認することです。データはサーバーから C に保存され、その後 B にインポートされます。このデータのバッチは、次のジョブの実行時に A に転送されます。図 1 に示すように:
同時に、安全性を確保し、トラブルシューティングを容易にするために、データベース インスタンス全体を記録するストアド プロシージャを使用して、ジョブの実行結果を短時間で確認する必要があります。異常な障害が発生した場合は、他の手段で関係者に通知してください。たとえば、電子メールと SMS テーブルに書き込み、Tcp 通知プログラムに定期的に読み取りと送信を行わせるなどです。
注: 1 日のデータが数十 GB に達し、このテーブルにクエリ要件がある場合 (パーティショニングについては後述します)、最良のオプションの 1 つは次のとおりです:
B は、次の方法で複数のサーバーに同期できます。同時に、クエリのプレッシャーを共有し、リソースの競合を減らします。データベース全体のリソースは限られているため、たとえば、挿入操作ではまず共有ロックを取得し、次にクラスター化インデックスを通じて特定のデータ行を見つけて、それを SQL Server が適用する必要がある目的のロックにアップグレードします。データのサイズに基づいて異なるロックを使用してロック メモリを維持するため、リソースの競合が発生します。したがって、読み取りと書き込みは可能な限り分離する必要があり、ビジネス モデルまたは設定されたルールに従って分割することができます。プラットフォーム ベースのプロジェクトでは、データを効率的に挿入できることを優先する必要があります。
避けられないビッグ データのクエリは大量のリソースを消費します。バッチ削除が発生した場合は、周期的なバッチ (一度に 2000 アイテムなど) に切り替えることができます。これにより、このプロセスによってデータベース全体が削除されなくなります。ハングアップすると、予期しないバグが発生します。実践すると、これは効果的で実現可能ですが、ストレージスペースが犠牲になるだけです。もちろん、テーブル内の大量のデータを含むフィールドは、クエリ要件に応じて新しいテーブルに分割することもできます。これらは、各ビジネス シナリオのニーズに応じて設定する必要があり、派手ではない適切なソリューションを設計できます。
2. ストレージの問題を解決する
1 つのテーブル内のデータが毎日数十ギガバイトに達する場合、ストレージ ソリューションを改善するのは当然です。ここで、急増するデータの被害にもかかわらず、最前線に留まり続けるための私自身の計画を共有したいと思います。以下は、私自身の環境に関する私の謙虚な意見を共有するための例です。
既存のデータ テーブル A、単一のテーブルは毎日 30G のデータを追加し、ストレージ中に非同期データ同期を使用します。データを消去できない一部のテーブルは、その後も消去できます。ファイル グループを複数のファイル グループに分割し、ファイル グループを異なるディスクに割り当てることで、IO リソースの競合を減らし、既存のリソースが正常に動作するようにします。現在、履歴データは次の要件に基づいて 5 日間保持されます。
1. 現時点では、ユーザー ID または時間フィールドに基づくパーティション化など、パーティション関数に基づいてパーティション化計画を生成するためにジョブを使用する必要があります。
2. テーブルがパーティション化された後、クエリは対応するインデックスを介して特定のパーティションを素早く見つけることができます。
3. パーティションの結合ジョブを通じて不要なパーティションデータをテーブルに転送し、削除します。この表のデータ。
図 2 に示すように:
SQL クエリ追跡を通じて長いクエリ時間をキャプチャし、SQL またはビューに付属するストアド プロシージャ sp_lock を通じて現在のインスタンスに存在するロックのタイプと粒度を確認します。 dm_tran_locks と dblockinfo。
特定のクエリ ステートメントまたはストアド プロシージャを見つけたら、適切な薬を処方してください。薬で病気が治る!
以上がこの記事の内容です。この記事の内容が皆さんの勉強や仕事に少しでもお役に立てれば幸いです。また、PHP中国語ウェブサイトも応援したいと思っています。
Sqlserver の高同時実行性とビッグ データ ストレージ ソリューションに関連するその他の記事については、PHP 中国語 Web サイトに注目してください。