大量のテーブルデータの読み取りと書き込みの速度を最適化する方法(1)[コールドとホットの分離]

今日お話しする内容は、ホットとコールドの分離です。コンセプトはなじみがなく、使用シナリオもおなじみですが、ロックの内容については慎重に検討する必要があります。まだ多くの「落とし穴」があります。私たちの実際の開発。

ビジネスシナリオ1

サプライチェーンに関連する構造最適化を経験しました。当時、プラットフォームには注文機能があり、メインテーブルには数千万のデータがあり、データ量は数億の関連テーブルに達しました。
このように大量のデータがあると、プラットフォームのクエリの順序が非常に遅くなります。クエリには20〜30秒かかり、さらに数回クリックするとダウンタイムが発生します。たとえば、営業担当者が複数のクエリを実行すると、データベースのCPUがすぐに急上昇し、サーバースレッドをドロップできなくなります。

当時、テーブル構造、ビジネスコード、インデックス、SQLステートメントなどのメソッドを最適化して応答速度を向上させようとしましたが、これらのメソッドは根本原因ではなく症状を処理し、クエリ速度は依然として非常に遅いです。

対処する必要のある他の優先度の高い要件があることを考慮して、ビジネス側に報告します。「将来この機能を使用しない場合は、必要ありません。しばらくの間、そのままにしてください。でも、しばらくすると、ビジネス側は本当に我慢できなくなったので、残酷に話すように言いましたが、必死になって屈服しました。

最終的に、この問題を簡単かつ便利に解決するために、費用対効果の高いソリューションを採用することにしました。データを処理する際、データベースを2つのライブラリに分割しました。コールドストレージとホットストレージ、コールドストレージに保存される使用頻度の低いデータ、および発熱ストレージの使用頻度の高いデータです。

このように処理した後、営業担当者は基本的に最近よく使用するデータをクエリするため、一般的に使用するデータの量が大幅に削減され、ダウンタイムが発生せず、データベースの応答速度も大幅に向上しました。

実際、上記の方法は「コールドセパレーションとホットセパレーション」です。

1.コールドセパレーションとホットセパレーションとは

コールドストレージとホットセパレーションは、データを処理するときにデータベースをコールドストレージとホットストレージに分割することです。コールドストレージとは、最終状態に達したデータを格納するデータベースを指し、ホットストレージとは、データを格納するデータベースを指します。変更する必要があります。

2.どのような状況でコールドセパレーションとホットセパレーションが使用されますか?

ビジネス要件が次のとおりであると仮定すると、コールドおよびホット分離ソリューションの使用を検討できます。

  • データが最終状態に達した後は、注文完了状態などの読み取り要件のみがあり、書き込み要件はありません。
  • ユーザーは新旧のデータの個別のクエリを受け入れることができます。たとえば、一部のeコマースWebサイトでは、デフォルトで3か月以内の注文のみをクエリできます。3か月前の注文をクエリする場合は、別のページにアクセスする必要もあります。

三、冷熱分離のアイデアの実現

実際の運用プロセスでは、冷熱分離の全体的な実現アイデアは次のとおりです:

1.データがコールドデータであるかホットデータであるかを判断するにはどうすればよいですか?

2.ホットデータとコールドデータの分離をトリガーするにはどうすればよいですか?

3.ホットデータとコールドデータの分離を実現するにはどうすればよいですか?

4.ホットデータとコールドデータの使用方法は?

次に、上記の4つの質問の詳細な分析を行います。

(1)データがコールドデータかホットデータかを判断するにはどうすればよいですか?

一般的に、データがコールドデータであるかホットデータであるかを判断する場合、主にメインテーブルの1つ以上のフィールドの組み合わせを区別する指標として使用します。その中で、このフィールドは「注文時間」フィールドなどの時間ディメンションにすることができ、3か月前の注文データをコールドデータ、3か月以内のデータをホットデータと見なすことができます。

もちろん、このフィールドはステータスディメンションにすることもできます。たとえば、「注文ステータス」フィールドに従って、完了した注文をコールドデータとして、未完了の注文をホットデータとして区別します。

フィールドの組み合わせを使用して区別することもできます。たとえば、注文期間が3か月を超え、ステータスが「完了」の注文をコールドデータとしてマークし、その他をホットデータとしてマークします。

実際の仕事では、最終的にどの分野が判断に使用されるかは、実際のビジネスに応じて決定する必要があります。

ホットデータとコールドデータを判断するロジックに関して、注意すべき2つの重要なポイントがあります。

  • データの一部がコールドデータとしてマークされている場合、ビジネスコードはそのデータに書き込みません。
  • コールド/ホットデータを同時に読み取る必要はありません。

(2)ホットデータとコールドデータの分離をトリガーする方法は?

ホットデータとコールドデータの判断ロジックを理解した後、ホットデータとコールドデータの分離をトリガーする方法を検討し始めます。一般的に、コールドデータとホットデータを分離するためのトリガーロジックには3つのタイプがあります。

1.ビジネスコードを直接変更し、データが変更されるたびにコールドとホットの分離をトリガーします(たとえば、注文のステータスが更新されるたびに、このロジックがトリガーされます)。

2.元のビジネスコードを変更したくない場合は、データベース変更ログのbinlogを監視することでトリガーできます(データベーストリガーも使用できます)。

3.データを定期的にスキャンすることによってトリガーされます(トリガーするデータベースタイミングタスクまたはプログラムタイミングタスク)。

上記の3つのトリガーロジックの場合、どちらが優れていますか?次の表の分析を読んだ後、あなたはあなたの心の中で答えを得るでしょう。

書き込み操作のビジネスコードを変更します データベースの変更ログを監視する データベースを定期的にスキャンする
利点 1.コードは柔軟で制御可能です。2.リアルタイムの保証 1.ビジネスコードから切り離します。2.低レイテンシーを実現できます。 1.ビジネスコードから切り離します。2.時間に基づいてホットデータとコールドデータを区別するシーンをカバーできます。
不利益 1.時間によってホットとコールドを区別することはできません。データがコールドデータになると、その期間中は操作を実行できません。2.すべてのデータ書き込み操作のコードを変更する必要があります。 1.時間によってホットとコールドを区別することはできません。データがコールドデータになると、その期間中は操作が実行されません。2.データの同時操作の問題を考慮する必要があります。つまり、ビジネスコードとホットおよびコールド変更コードは同じデータに対して同時に動作します。 1.リアルタイムを達成できない

表の内容の比較によると、各開始ロジックの推奨シナリオを取得できます。

  1. 書き込み操作のビジネスコードを変更する:ビジネスコードが比較的単純で、時間によってホットデータとコールドデータを区別しない場合に使用することをお勧めします。
  2. データベース変更ログの監視:ビジネスコードが複雑で、自由に変更できず、時間によってホットデータとコールドデータを区別しない場合に使用することをお勧めします。
  3. データベースを定期的にスキャンする:ホットデータとコールドデータを時間で区別する場合に使用することをお勧めします。

(3)ホットデータとコールドデータを分離する方法は?

ホットデータとコールドデータを分離するための基本的なロジックは次のとおりです。

1.データがコールドかホットかを判断します。

2.分離するデータをコールドデータに挿入します。

3.分離されたデータをホットデータベースから削除します。

この論理は単純に見えますが、実際に計画を立てる際には、以下の3点を考慮する必要があり、単純ではありません。

(1)整合性:データベースを同時に変更した後、データの整合性を確保する方法

ここに記載されている整合性要件は、ステップエラーが発生した後、データの整合性を確保する方法を示しています。解決策は、各ステップを再試行でき、演算がべき等であることを確認することです。特定のロジックは4つのステップに分かれています。

  • ホットデータベースで、移動するデータにフラグを追加します:flag = 1。(1はコールドデータを表し、0はホットデータを表します)

  • 移動するすべてのデータを確認する(flag = 1):この手順は、何らかの理由で一部のスレッドが失敗し、移動する一部のデータが移動されないようにするためです。

  • データのコピーをコールドデータベースに保存しますが、べき等性を確保するために保存ロジックに判断を追加する必要があります(ここではトランザクションで囲む必要があります)。素人の言葉で言えば、保存するデータがコールドデータベースにすでに存在する場合、このロジックを続行できることを確認してください。

  • ホットデータベースから対応するデータを削除します。

(2)大量のデータ:データ量が多く、一度に処理できない場合はどうすればよいですか?バッチ処理を使用する必要がありますか?

上記の冷熱を分離する3種類のトリガーロジック、最初の2種類は基本的に大量のデータの問題はありません。これは、そのたびに変更されるデータを操作するだけでよいためです。タイミングスキャンのロジックを使用するには、データを考慮する必要があります。この問題を測定してください。

この実装ロジックも非常にシンプルで、データを移動するバッチロジックを追加できます。理解を容易にするために、例を見てみましょう。

毎回50個のデータを移動できると仮定します。

a。ホットデータベースに移動するデータにマークを追加します:flag = 1;

b。移動する最初の50個のデータを見つけます(フラグ= 1)。

c。データのコピーをコールドデータベースに保存します。

d。対応するデータをホットデータベースから削除します。

e。ループでbを実行します。

(3)同時実行性:データ量が多すぎて並列処理のために複数の場所に分散する必要があると仮定すると、どうすればよいですか?

ホットデータとコールドデータが定期的に(毎日など)転送されるシナリオで、毎日処理されるデータの量が多すぎてシングルスレッドのバッチ処理には遅すぎる場合は、どうすればよいですか?現時点では、並行処理のために複数のスレッドを開くことができます。(ほとんどの場合、マルチスレッドの方が高速ですが、この状況が発生しました。シングルスレッドのバッチサイズが特定の値に達すると、効率が特に高く、マルチスレッドのバッチサイズよりも高速になります。したがって、料金を支払う必要があります。注意:マルチスレッドの速度が速くない場合は、シングルスレッドの制御を検討します。)

複数のスレッドがホットデータとコールドデータを同時に運ぶ場合、次の実装ロジックを考慮する必要があります。

ステップ1:マルチスレッドを開始する方法は?

タイマートリガーロジックを使用しているため、ロジックをトリガーする最も費用効果の高い方法は、複数のタイマーを設定し、各タイマー間の間隔を短くして、スレッドが定期的に開始されるたびにデータの移動を開始することです。

もう1つのより適切な方法は、自分でスレッドプールを構築してから、定期的に次の操作をトリガーすることです。最初に移動するホットデータの数を計算し、次に同時に開始するスレッドの数を計算します。スレッドプールの数よりも大きい場合は、スレッドプール内のスレッドの数を取得します。この数をNとすると、スレッドプールを開始するスレッドはN回ループされ、ホットデータとコールドデータを伝送します。

ステップ2:スレッドがデータ操作をアナウンスし、他のスレッドは移動(ロック)しません。

このロジックに関して、3つの特性を考慮する必要があります。

  • ロック取得のアトミック性:スレッドが、処理される特定のデータがロックされていないことを検出し、それをロックする場合、これら2つの操作はアトミックである必要があります。つまり、一緒に成功するか、一緒に失敗します。実際の操作は、最初にLockThreadフィールドとLockTimeフィールドをテーブルに追加し、次にSQLステートメントを使用して移行するロック解除またはロックタイムアウトデータを見つけ、次にLockThread =現在のスレッド、LockTime =現在の時間を更新し、最後にMySQLアップデートロックメカニズムはアトミック性を実現します。

  • ロックの取得は、処理の開始と一致している必要があります。現在のスレッドがこのデータの処理を開始するときに、操作のデータが現在のスレッドによって正常にロックされているかどうかを再度確認する必要があります。実際の操作は、LockThreadをクエリすることです。 =現在のスレッドのデータを再度実行し、クエリを処理します。データ。

  • ロックの解放は、処理の完了と一致している必要があります。現在のスレッドがデータを処理した後、ロックを解放する必要があります。

    ステップ3:スレッドが正常に処理された後、データはホットストレージにはなく、コールドストレージに直接実行されます。これは通常のロジックですが、特に注意する必要はありません。

    ステップ4:スレッドが失敗して終了したが、ロックが解放されなかった場合(ロックタイムアウト)はどうなりますか?

    ロックを解除できない:データをロックしたスレッドが異常終了し、ロックを解除するには遅すぎて、他のスレッドがデータを処理できなくなった場合、この時点でどうすればよいですか?解決策は、ロックのタイムアウト期間を設定することです。ロックタイムアウトが解除されていない場合、他のスレッドはデータを正常に処理できます。

    タイムアウト期間を設定するときは、処理中のデータが原因でタイムアウトが発生したために、処理中のスレッドが終了しない場合の対処方法も考慮する必要があります。解決策は、タイムアウト時間をデータ処理の妥当な時間を超えるように設定することです。ホットデータとコールドデータを処理するためのコードは、べき等であることが保証されている必要があります。

    最後に、極端なケースを考慮する必要があります。現在のスレッドロックデータがまだ処理中であり、データがこのタイムアウトで処理されており、別のスレッドがデータがロックされていることを処理している場合、今回はどうすればよいですか?ホットデータとコールドデータを処理するためのコードは比較的単純であり、この操作による現在のスレッド処理によってデータの整合性が損なわれることはないため、各ステップでフォールトトレランスを追加するだけで済みます。

(4)コールドデータの使い方

機能設計のクエリインターフェイスには、通常、コールドデータとホットデータのどちらをクエリする必要があるかを選択するオプションがあります。インターフェイスで提供されていない場合は、ビジネスコードで直接区別できます。(注:コールドデータかホットデータかを判断するときは、ユーザーがホットデータとコールドデータを同時に読み取れないようにする必要があります。)

履歴データを移行する方法は?
一般的に言えば、永続層に関連するアーキテクチャソリューションである限り、履歴データの移行、つまり、古いアーキテクチャの履歴データを新しいアーキテクチャに適用する方法を検討する必要があります。

以前の分離ロジックは失敗の再試行シナリオを検討するときにこの問題をカバーするだけなので、この問題の解決策も非常に簡単です。すべての履歴データをマークするだけで済みます。flag= 1の後、プログラムは自動的に移行されます。

コールドおよびホット分離ソリューションの不足

コールドとホットの分離ソリューションは、書き込み操作とホットデータの速度低下の問題を実際に解決できると言わざるを得ませんが、それでも多くの欠点があります。

1未満:ユーザーのクエリデータの速度はまだ非常に遅いですユーザーのクエリデータの割合が1%しかない場合など、このプログラムは問題ありません。

2つ未満:コールドデータなど、ある程度はシステムが耐えられないため、ビジネスデータをコールドで変更することはできません。(この点は、後で説明するコールドストレージとサブストレージによって解決できます)

おすすめ

転載: blog.51cto.com/11996285/2644153