Redis - キャッシュなだれ、キャッシュの侵入、キャッシュのブレークダウン

 Redis は、BSD プロトコルに準拠した完全にオープン ソースの高性能キー/値データ ストレージ構造システムであり、データの永続性をサポートし、データをディスク上のメモリに保存できます。単純なキーと値のデータ構造をサポートするだけでなく、リスト、zset、ハッシュ、およびその他のデータ構造ストレージも提供します。Redis は、マスター/スレーブ モードでのデータ バックアップもサポートしています。最も重要なことは、Redis の読み取りと書き込みが高速であることです。実際のアプリケーションでは、Redis ではキャッシュなだれ、キャッシュの侵入、キャッシュの故障などの異常な状況が発生します。

概要

1. キャッシュ雪崩: Redis 内の多数のキーがまとめて期限切れになる

2. キャッシュの侵入: まったく存在しないキーに対する大量のリクエスト

3. キャッシュの内訳: Redis のホットスポット キーの有効期限が切れます (多数のユーザーがホットスポット キーにアクセスしますが、ホットスポット キーの有効期限が切れます)

1. キャッシュアバランシェソリューション

  • ホットワードを事前に設定し、キーの長さを調整します
  • リアルタイム調整、どのデータが人気データであるかの監視、キー有効期限のリアルタイム調整
  • ロック機構を使用する

2. キャッシュペネトレーションソリューション

  • 空の値をキャッシュする
  • ホワイトリストを設定する
  • ブルームフィルターを使用する
  • インターネット警察

3. キャッシュブレークダウンソリューション

  • ホットワードを事前に設定し、キーの長さを調整します
  • リアルタイム調整、どのデータが人気データであるかの監視、キー有効期限のリアルタイム調整
  • ロックメカニズムを使用する (ホットデータを再構築できるのは 1 つのスレッドのみ)

Redis キャッシュ ミドルウェアは次のように動作します。

クライアントがクエリ リクエスト リクエストを開始すると、データが Redis キャッシュに存在する場合はまず Redis キャッシュにアクセスしてクエリを実行し、データがキャッシュに存在しない場合はキャッシュ内のデータをクライアントに直接返します。 、データベース DB へのクエリを続行します。データがデータベース DB に存在する場合は、データを Redis キャッシュに入れてクライアント クライアントに返します。データがデータベース DB に存在しない場合は、クライアント クライアントに直接 null を返します。

キャッシュ雪崩、キャッシュペネトレーション、キャッシュブレークダウンの根本原因: Redis ヒット率が低下し、リクエストが DB に直接ヒットします。

通常の状況では、大量のリソース要求は redis で応答され、redis で応答できないリクエストのごく一部のみが DB を要求するため、DB への負荷は非常に小さく、正常に動作します。 (下図に示すように)

Redis 上で多数のリクエストが応答されない場合、これらのリクエストは DB に直接アクセスするため、DB への負荷が即座に増大し、スタックまたはダウンが発生します。

1. 大量の高度な同時リクエストが Redis に送信される

2. これらのリクエストでは、redis 上にリクエストする必要があるリソースがないことがわかり、redis のヒット率が低下します。

3. したがって、これらの多数の同時リクエストは DB (データベース サーバー) に送られ、対応するリソースをリクエストします。

4. DB への圧力が瞬時に高まり、DB が直接破壊され、一連の「災害」が引き起こされます。

現象 キャッシュ雪崩 キャッシュの侵入 キャッシュの内訳
リソースがDBデータベースサーバーに存在するかどうか
リソースが Redis に存在するかどうか
Redisに対応するリソースがない理由 ほとんどのキーはまとめて期限切れになります リソースがまったく存在しません (DB も存在しません) ホットスポットキーの有効期限が切れています
根本的な原因 同時実行性の高いリクエストが大量に Redis に送信されるが、Redis にリクエストされたデータが存在しないことが判明し、Redis のオーダー率が低下するため、これらのリクエストは DB (データベース サーバー) に直接送信することしかできません。 . DB が直接スタックしてダウンする原因となります。

1. キャッシュ雪崩

キャッシュなだれとは、キャッシュ内の多数のキーの有効期限が同時に切れたり、Redis が直接クラッシュしたりして、多数のクエリ リクエストがデータベースに到達し、その結果データベースのクエリ圧力が突然増加することを指します。直接電話を切るとシステム全体がクラッシュし、雪崩のような連鎖現象が発生します。

問題の原因

1. 大量のキャッシュされたデータが同時に期限切れになるため、キャッシュを要求する必要があるときにデータベースからデータを再度取得する必要があります。

2. Redis 自体に障害が発生してリクエストを処理できない場合、当然のことながらデータベースに再度リクエストが行われます。

解決

1. 多数のキーの同時有効期限切れ

[1] 有効期限を分散する; 自動乱数生成、微調整、均一設定などにより、鍵の有効期限をランダム化し、一括有効期限切れを防止します。

[2] マルチレベル アーキテクチャを使用します。nginx キャッシュ + Redis キャッシュ + その他のキャッシュを使用し、異なるレイヤーは異なるキャッシュを使用し、信頼性が強化されます。

[3] キャッシュ フラグを設定します。キャッシュ データの有効期限が切れているかどうかを記録します。期限が切れた場合は、別のスレッドへの通知をトリガーして、バックグラウンドで実際のキーを更新します (スケジュールされたタスクまたはメッセージ キューを使用して、Redis を更新または削除します)キャッシュなど)

[4] キャッシュ構築と同時にミューテックスを追加しないようにする

2. Redis に対して障害が発生しました

[1] 防止レベルでは、マスター/スレーブ ノード モードを通じて高可用性クラスターを構築します。これにより、マスター Redis がハングアップした後、他のスレーブ データベースがすぐにマスター データベースに切り替えてサービスを提供し続けることができます。

[2] 大量のリクエストによるデータベースのクラッシュを防ぐために、サービスの融合またはリクエスト フロー制限を使用できます。サービス ヒューズは比較的緩やかで、Redis サービスが復元されるまでサービスを停止します。リクエスト フローの制限は、一部のリクエストを確実に処理できるように比較的緩やかです。

2. キャッシュの侵入

キャッシュの侵入とは、データが Redis キャッシュにも DB データベースにも存在しないことを意味し、その結果、リクエストが来るたびに、Redis キャッシュで対応するキーが見つからなかった後、毎回 DB データベースに再度クエリを実行する必要があります。 DB データベースに存在しないことがわかります。これは、無効なクエリを 2 回実行することに相当します。

このようにして、リクエストは Redis キャッシュをバイパスし、DB データベースに直接クエリすることができます。システムを攻撃する悪意のあるハッカーがいる場合、空の値またはその他の存在しない値を使用して頻繁にリクエストを行うことができます。データベースに多大な負荷がかかるか、場合によっては電話が切れてしまいます。

解決

1. 空の値またはデフォルト値をキャッシュする

Redis キャッシュからデータを取得できず、DB データベースからもデータを取得できない場合でも、結果は引き続きキャッシュされ、同時に短い有効期限が設定されます。

2. 不正請求の規制

パラメータ検証、認証検証、大量の不正なリクエストを初期段階で遮断し、これらのリクエストがRedisやDBに到達しないようにする

3. ブルームフィルター

ブルームフィルタは、長さmビットのビット配列とn個のハッシュ関数で構成されるデータ構造であり、ビット配列の各要素の初期値は0です。ブルーム フィルターを初期化するとき、最初にすべてのキーが n 回ハッシュ化されて、n 個の位置が取得され、その後、これらの n 個の位置の要素が 1 に変更されます。この方法では、ブルーム フィルター内のすべてのキーを保存することと同じになります。

たとえば、合計 3 つのキーがある場合、これら 3 つのキーに対して 3 回のハッシュ操作を実行し、3 回のハッシュ操作後の key1 の結果は 2/6/10 となり、ブルーム フィルターをマークされた要素の値に置きます。 2/6/10 が 1 に更新され、同じ操作が key2 と key3 に対してそれぞれ実行され、結果は次のようになります。

このようにして、クライアントがクエリを実行すると、クエリされたキーに対して 3 つのハッシュ操作を実行して 3 つの位置を取得し、ブルーム フィルター内の対応する位置要素の値が 1 であるかどうかを確認します。対応する位置要素の値が 1 である場合、キーがライブラリ内に存在することが証明され、下向きのクエリが続行されます。3 つの位置のいずれかの値が 1 でない場合、キーがライブラリ内に存在しないことが証明されます。ライブラリを作成し、クライアントを直接空に戻すだけで十分です。以下に示すように:

クライアントが key4 にクエリを実行すると、key4 の 3 つのハッシュ操作で、位置 8 に 0 の値が存在します。これは、key4 がライブラリに存在しないことを意味し、クライアントは直接空を返すことができます。

したがって、ブルーム フィルターはクライアントとキャッシュ層の間のインターセプターに相当し、キーがコレクションに存在するかどうかを判断する役割を果たします。以下に示すように:

ブルームフィルタの利点は、最初のタイプのキャッシュnull値の欠陥を解決できることですが、ブルームフィルタにも欠陥があります。第一に、判断を誤る可能性があります。たとえば、上図で、クライアントがkey4を問い合わせる場合、key4が合格した場合、 3 つのハッシュ演算で得られる位置はそれぞれ 2/4/6 であり、これら 3 つの位置の値はすべて 1 であるため、ブルーム フィルターは key4 がライブラリに存在すると考え、下方向にクエリを続けます。したがって、ブルームフィルタが存在すると判断したキーは実際には存在しない可能性があるが、ブルームフィルタが存在しないと判断したキーは存在してはいけない。2 番目の欠点は、要素の削除が難しいことです。たとえば、要素 key2 を今削除したい場合、2/7/11 の 3 つの位置の要素の値を 0 に変更する必要がありますが、これにより削除されます。 key1とkey3の判定に影響を与える

3. キャッシュの内訳

キャッシュ ブレークダウンとは、キャッシュ内のホット データの有効期限が切れると、ホット データがキャッシュに再ロードされる前に、大量のクエリ リクエストがキャッシュを通過し、データベースに直接クエリを実行することを意味します。この状況により、データベースへの負荷が急激に増加し、多数のリクエストがブロックされたり、直接ハングアップしたりすることがあります。

キャッシュのブレークダウンは通常、同時実行性の高いシステムで発生します。このシステムでは、多数のユーザーが Redis キャッシュにはなく DB データベースにあるデータを同時に要求します。つまり、リード キャッシュはデータを読み取らず、同時に DB データベースからデータをフェッチするため、データベースへの負荷が瞬時に増加します。

キャッシュアバランシェとキャッシュブレークダウンの違い

キャッシュのブレイクダウンとは、同じデータ部分を指します。キャッシュ雪崩とは、異なるデータの有効期限が切れ、データベース内で多くのデータがクエリされることを意味します。

解決

1. ホットスポット キーを設定するときは、キーの有効期限を設定しないでください。

ホットスポット キーを設定するときは、キーの有効期限を設定しないでください。ただし、キーを期限切れにしないという目的を達成する別の方法があります。それは、キーの有効期限を通常どおりに設定し、スケジュールされたタスクをバックグラウンドで開始してキャッシュを定期的に更新することです。

2. 分散ロックを使用して、1 つのクエリ リクエストのみが同時にホットスポット データをキャッシュにリロードするようにします。

ロック方式を採用しており、ロックの対象となるのはキーであるため、同じキーに対するリクエストが同時に大量に送信された場合、ロックを取得できるのは 1 つのリクエストだけであり、その後、ロックを取得したスレッドがロックを取得します。 lock はデータベースにクエリを実行し、その結果をキャッシュに格納して、ロックを解放します。この時点で、ロックを待機している他のリクエストは引き続き実行できます。この時点ではすでにキャッシュにデータがあるため、データはキャッシュから直接取得され、データベースにクエリを実行せずに返されます。

要約する 

https://www.zhihu.com/question/484022509

キャッシュの侵入、キャッシュのブレークダウン、キャッシュなだれとその解決策を 1 つの記事で読んで理解します。

Redisのキャッシュ侵入・雪崩・故障の原因と解決策(詳しく解説)_redisキャッシュ故障_PeakXYHのブログ - CSDNブログ

おすすめ

転載: blog.csdn.net/MinggeQingchun/article/details/130400887