ホームページ  >  記事  >  データベース  >  Redis キャッシュの一貫性、キャッシュの侵入、キャッシュの破壊、キャッシュなだれの問題を一緒に分析しましょう

Redis キャッシュの一貫性、キャッシュの侵入、キャッシュの破壊、キャッシュなだれの問題を一緒に分析しましょう

WBOY
WBOY転載
2022-05-19 10:12:202068ブラウズ

この記事では、Redis に関する関連知識を提供し、主にキャッシュの整合性、キャッシュの侵入、キャッシュの破壊、キャッシュなだれ、キャッシュされたデータの書き込み同期に関連する問題を紹介します。 DB の整合性の確認。皆様のお役に立てれば幸いです。

Redis キャッシュの一貫性、キャッシュの侵入、キャッシュの破壊、キャッシュなだれの問題を一緒に分析しましょう

関連する推奨事項: 「Redis におけるホット キー ストレージの問題の分析と、例外をキャッシュするための解決策について語る

(1) キャッシュ無効化の一貫性の問題

キャッシュの一般的な使用方法は、まずキャッシュを読み取り、キャッシュが存在しない場合は DB から読み取ります。結果はキャッシュに書き込まれ、次回データを読み取るときに、データをキャッシュから直接取得できます。 [関連する推奨事項: Redis ビデオ チュートリアル ]

データ変更では、キャッシュされたデータを直接無効にしてから、DB の変更は成功してもキャッシュされたデータが無効になることを避けるために DB コンテンツを変更します。ネットワークまたはその他の問題によりクリアされず、データがダーティになります。ただし、これでもダーティ データの生成を避けることはできません。同時シナリオの場合: ビジネスでデータ Key:Hello Value:World に対する読み取りおよび変更リクエストが多数あると仮定します。スレッド A は OCS から Key:Hello を読み取り、Not Found 結果を取得し、DB からデータの要求を開始し、データ Key:Hello Value:World を取得します。次に、このデータを OCS に書き込む準備をしますが、OCS に書き込む前に (ネットワークCPU の待機により、スレッド A の処理速度が低下する可能性があります。) 別のスレッド B がデータ Key:Hello Value:OCS の変更を要求し、最初に無効化キャッシュ アクションを実行します (スレッド B はこのデータが存在するかどうかを知らないため) 、そのため、無効化操作が直接実行されます) OCS は無効なリクエストを正常に処理しました。スレッド A に戻って OCS の書き込みを続行し、Key:Hello Value:World をキャッシュに書き込みます。スレッド A のタスクは終了し、スレッド B も DB データ コンテンツを Key:Hello Value:OCS に正常に変更しました。この問題を解決するために、OCS は Memcached プロトコルを拡張し (パブリック クラウドが間もなくサポートする予定です)、deleteAndIncVersion インターフェイスを追加しました。このインターフェイスは実際にはデータを削除しませんが、データに有効期限が切れたことを示すラベルを付け、データのバージョン番号を増やします。データが存在しない場合は、NULL が書き込まれ、ランダムなデータ バージョン番号も生成されます。 OCS の書き込みでは、バージョン番号のアトミックな比較がサポートされています。受信したバージョン番号が OCS によって保存されたデータのバージョン番号と一致しているか、元のデータが存在しないと仮定すると、書き込みが許可されます。そうでない場合は変更が拒否されます。

先ほどのシーンに戻ります: スレッド A は OCS から Key:Hello を読み取り、Not Found 結果を取得し、DB からデータの要求を開始し、データ Key:Hello Value:World を取得して、書き込みの準備をします。 OCS このデータ部分のバージョン番号情報のデフォルトは 1 です。A が OCS に書き込む前に、別のスレッド B がデータ Key:Hello Value:OCS を変更するアクションを開始します。最初にキャッシュの削除アクションが実行されます。OCS は、キャッシュの削除アクションを正常に処理します。 deleteAndIncVersion リクエストを実行し、ランダムなバージョン No. 12345 (1000 より大きいことが合意) を生成します。スレッド A に戻り、Key:Hello Value:World の書き込みを要求して OCS への書き込みを続けます。この時点で、キャッシュ システムは、受信したバージョン番号情報が一致しない (1! = 12345) ことを検出し、書き込みは失敗し、スレッド A のタスクが終了します。;スレッド B も DB データ コンテンツを Key:Hello Value:OCS に正常に変更しました。

現時点では、OCS のデータは Key:Hello Value:NULL バージョン:12345、DB のデータは Key:Hello Value:OCS です。後続の読み取りタスクでは、DB のデータが再試行されます。 OCS に書き込みます。

(2) キャッシュされたデータの書き込み同期と DB との整合性の問題

Web サイトの規模が拡大し、信頼性が向上するにつれて、複数の IDC の導入が課題となります。各 IDC は独立した DB およびキャッシュ システムを備えており、キャッシュの一貫性が顕著な問題となっています。

まず第一に、高効率を確保するために、キャッシュ システムは BINLOG を書き込んでいる場合でもディスク IO を防止します。もちろん、パフォーマンス上の理由から、キャッシュ システムは同期削除のみが可能であり、削除はできません。書き込みは同期的に行われるため、通常はキャッシュ同期が DB 同期の到着よりも優先されます (結局のところ、キャッシュ システムの方がはるかに効率的です)。その場合、キャッシュにデータがなく、DB に古いデータが存在するシナリオが発生します。このとき、業務からデータの要求があり、リードキャッシュが見つかりません。DBから読み出してキャッシュにロードした古いデータは古いデータのままです。DBのデータ同期が来ると、DBのみが更新されます。また、キャッシュされたダーティ データはクリアできません。

Redis キャッシュの一貫性、キャッシュの侵入、キャッシュの破壊、キャッシュなだれの問題を一緒に分析しましょう

上記の状況からわかるように、不整合の根本原因は、異種システムが連携して同期できないことです。DB データが最初に同期され、キャッシュされたデータが保証されるわけではありません。後で同期されます。したがって、キャッシュ システムが DB 同期をどのように待機するか、あるいは 2 つのキャッシュ システムが同期メカニズムを共有できるかを検討する必要があります。キャッシュ同期も DB BINLOG に依存しており、これは実現可能なソリューションです。

IDC1 の DB は、BINLOG を通じて IDC2 の DB に同期されます。この場合、IDC2-DB データ変更により独自の BINLOG も生成されます。キャッシュされたデータの同期は、IDC2-DB BINLOG を通じて実行できます。キャッシュ同期モジュールは、BINLOG を分析した後、対応するキャッシュ キーを無効にし、同期をパラレルからシリアルに変更して順序を保証します。

(3) キャッシュの侵入 (DB に不要なクエリトラフィックが発生)

方法 1: ブルーム フィルターです。これは、要素がセット内にあるかどうかを判断するために使用される、非常にスペース効率の高い確率的アルゴリズムとデータ構造です (ハッシュセットと同様)。そのコアは、長いバイナリ ベクトルと一連のハッシュ関数です。 Google の guava を使用してブルーム フィルターを実装します。 1) 誤計算率があり、格納する要素数が増えると誤算率も増加する 2) 通常、ブルームフィルタから要素を削除することはできない 3) 配列の長さと配列数を決定するプロセスハッシュ関数は複雑であり、配布 ロングフィルターの使用シナリオは何ですか? 1) スパム アドレス フィルタリング (アドレスの数は膨大です) 2) クローラー URL アドレスの重複排除 3) キャッシュの故障の問題を解決します

方法 2: 空の結果を保存し、空の結果の時間を設定します

(4) キャッシュなだれ (キャッシュが同じ有効期限に設定されているため、DB フラッドが発生します)

方法 1: ほとんどのシステム設計者は、単一スレッドを確実にキャッシュするためにロックまたはキューの使用を検討しています。 (プロセス) 失敗時に基盤となるストレージ システムに大量の同時リクエストが発生するのを避けるために書き込みを行う

方法 2: 失敗時間のランダムな値

(5) キャッシュの内訳 (ホット スポット) キー、多数の同時読み取りリクエストによって引き起こされる小さな雪崩)

キャッシュが特定の時点で期限切れになると、たまたま多数の同時読み取りリクエストが発生します。この時点でのこのキーに対するリクエスト これらのリクエスト キャッシュの有効期限が切れていることが判明した場合、通常、データはバックエンド DB からロードされ、キャッシュにリセットされます。このとき、大量の同時リクエストにより、瞬時にシステムが圧倒される可能性があります。バックエンド DB

方法 1: 1. 分散キャッシュを使用する サポートされているミューテックス キーに対してミューテックス キーを設定し、操作が正常に戻ると、ロード DB 操作が実行され、キャッシュが設定されます。つまり、DB のロードは 1 つのスレッドによってのみ処理されます。

方法 2: 事前にミューテックス キーを使用する: value 内にタイムアウト値 (timeout1) を設定し、timeout1 が実際の memcache タイムアウト (timeout2) よりも小さいように設定します。 、ただちにタイムアウト 1 を延長し、キャッシュにリセットします。次に、データベースからデータをロードしてキャッシュに設定します。これにより、ビジネス コードの侵入が増加し、コーディングの複雑さが増加します。

方法 3 : 「期限切れにならない」 ": Redis の観点から見ると、実際には有効期限が設定されていないため、ホットスポット キーの有効期限の問題は発生しません。つまり、「物理的」キーの有効期限が切れることはありません。機能的な観点から見ると、有効期限が切れていない場合は、 , 静的ではないので、キーに対応する値に有効期限を保存します。有効期限が近づいていることが判明した場合、キャッシュはバックグラウンドの非同期スレッドを通じて構築されます。これは「論理的」です。有効期限

(6) キャッシュ システムにおける一般的なキャッシュ フルとデータ損失の問題

##特定のビジネス分析に基づく必要があります。通常、オーバーフローを処理するために LRU 戦略を使用します。 、特定の状況を確実にするための Redis の RDB および AOF 永続化戦略。

プログラミング関連の知識の詳細については、

プログラミング ビデオ !! を参照してください。

以上がRedis キャッシュの一貫性、キャッシュの侵入、キャッシュの破壊、キャッシュなだれの問題を一緒に分析しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjianshu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。