前回の記事では、redis の基礎知識を中心にお話ししましたが、実際に戦闘したり、問題が発生したりすることはありません。皆さんにとっては退屈でしょう。実戦についてお話します。
これら 3 つの問題はすでにインターネット上で発生していると思います多くの友人がそれについて話しましたが、今日はまだ皆さんの印象を深めるためにもっと絵を描くと言いたいです この3つの質問は面接でもよく聞かれますが、これらの質問をわかりやすく説明するにはスキルが必要です。 [関連する推奨事項: Redis ビデオ チュートリアル ]
これら 3 つの質問について説明するときは、まず通常のリクエスト プロセスについて説明し、写真を見て話しましょう:
上の図の意味はおおよそ次のとおりです:
まず、コード内で、Tomcat または RPC サービスの場合があります。まず、必要なデータが存在するかどうかを確認します。キャッシュに保存されている場合は、呼び出し元に直接返されます。存在しない場合は、データベースにクエリを実行し、結果をクエリして、引き続きキャッシュにキャッシュしてから返す必要があります。結果は呼び出し元に送信され、次回クエリを実行するときにもキャッシュにヒットします。
定義
以前レコメンデーション システムを開発していたとき、一部のデータは次のように計算されていたことを思い出しました。オフラインアルゴリズム. 要件は、この製品を読んだ後、同様の製品を推奨することです. この計算の後、hbase と redis に同時に保存されます. これらはすべてバッチアルゴリズムによって生成されるため、redis に保存する場合、有効期限が切れた場合時間を同じに設定すると、多数のキーが同時に期限切れになり、大量のリクエストがバックグラウンド データベースにヒットします。データベースのスループットは限られているため、非常に可能性が高くなります。データベースをダウンさせます。このような状況です。この状況はキャッシュ雪崩です。絵を見て話してください:
#これは主に、キャッシュ雪崩が発生するシナリオ、特に次の場合について説明します。スケジュールされたタスクのキャッシュをバッチで設定する場合は、注意する必要があります有効期限の設定。
雪崩を防ぐ方法
実はとても簡単で、キャッシュのキャッシュ時間を一括設定する際に、乱数(例:乱数は 10 分以内の数値にすることができ、乱数は Java の Random を使用して生成できます。この方法では、多数のキーが同時に集合的に失敗することはありません。図を見てください。話します:
本当に雪崩が起きたらどうしますか?
トラフィックはそれほど大きくありません。データベースはそれに耐えることができます。無事、脱出できました。
トラフィックが非常に多く、データベースが処理できるリクエスト数の制限を超えています。データベースがダウンしています。P0 インシデント チケットの取得おめでとうございます。
トラフィックが非常に大きいです。データベースに電流制限スキームがある場合、電流制限設定で設定されたパラメータに達するとリクエストが拒否され、バックグラウンド データベースが保護されます。電流制限について少し説明します。
1 秒あたりのリクエスト数を設定することで、データベースの端に到達する大量のリクエストを制限できます。ここでの 1 秒あたりのリクエスト数、つまり同時実行数は、現在のリクエスト数ではないことに注意してください。データの 1 秒あたりのリクエスト数をクエリするように設定できます。これは、同じキーに対する大量のリクエストがバックエンド データベースに到達するのを防ぎ、ほとんどのリクエストは傍受される可能性があります。
写真を見て話してください:
このようにして、同じキーに対するほとんどのリクエストが制限され、データベース データベースが保護されます。
実は、電流制限にはローカル電流制限と分散電流制限の2種類があり、次の記事ではredisで実装されるローカル電流制限と分散電流制限について紹介します。
定義
たとえば、Web サイトがダブル イレブンを実施していたり、フラッシュ セールやその他の運営を行っているとします。アクティビティの場合、この時点で Web サイトのトラフィックは通常非常に大きくなります。特定の製品がプロモーションにより人気商品となり、トラフィックが非常に大きくなります。この時点でこの製品が何らかの理由でキャッシュに失敗した場合、 , その後、瞬時に、このキーのトラフィックがデータベースに流れ、データベースは最終的に保持できなくなり、ダウンします。その結果は想像できますが、他のデータを正常にクエリできなくなります。
写真を見て話してください:
Redis の huawei プロ キーが突然失敗しました。期限切れになったか、次の理由で削除された可能性があります。メモリが不足しているため、大量のリクエストが redis に到着し、redis にこのキーがないことが判明します。その後、これらのトラフィックは DB に転送され、対応する huawei pro にクエリが実行されます。この時点では、DB は耐えることができませんそれはもう下がります。
解決方法
実際、最終的な分析では、これ以上のトラフィックが DB に到達しないようにするだけで十分なので、DB に到達するトラフィックを制限するだけで十分です。 。
1. 電流制限
は上記と同様で、主に特定のキーのトラフィックを制限します。このキーが壊れると、トラフィックは 1 つだけになります。データベースに入ると他の人は拒否されるか、redis のクエリの再試行を待機します。
電流制限図については、キャッシュブレークダウン電流制限図を参照してください。
これは、ローカル電流制限と分散電流制限にも分けられます。
ローカル電流制限とは何ですか? 単一のローカル インスタンスの範囲内でこのキーのトラフィックを制限することを意味し、現在のインスタンスに対してのみ有効です。
分散型電流制限とは何ですか?分散環境では、複数のインスタンスの範囲内で、このキーの累積トラフィック制限が複数のインスタンスからのトラフィックであることを意味します。制限に達すると、すべてのインスタンスがトラフィックを制限します。 .DBに到達。
2. 分散ロックの使用
ここでは、分散ロックの定義について簡単に紹介します。同時シナリオでは、ロックは相互排他的アクセスを保証するために使用する必要があります。共有リソース、スレッド セーフ、同様に、分散シナリオでは、マルチノード共有リソースへの相互排他的アクセスを保証するためのメカニズムも必要であり、その実装メカニズムは分散ロックです。
ここでの共有リソースは、例では huawei pro です。つまり、データベース内の huawei pro にアクセスする場合、分散ロックの効果を実現するには、1 つのスレッドまたは 1 つのフローのみにアクセスする必要があります。
写真を見て話してください:
ロックを取得しに行きます:
多数のリクエストがhuawei pro キーの値を準備します データベースに移動してデータを取得します。このとき、データベースを取得するコードは分散ロックを追加します。その後、各リクエストと各スレッドは huawei pro の分散ロック (分散ロック) を取得します。図ではredisを利用して実装しています(後ほど説明します。redisに限らず分散ロックの実装については別記事で紹介します)。
ロック取得後:
この時点で、スレッド A は huawei pro の分散ロックを取得し、スレッド A は DB に移動してデータをロードします。 、そしてスレッド A によって huawei pro を再度キャッシュに設定し、データを返します。
他のスレッドはそれを取得していません。1 つの方法は、クライアントに直接 null 値を返すことです。もう 1 つの方法は、データベースのクエリと Redis への入力が非常に高速であるため、50 ~ 100 ミリ秒待つことです。 . この時点では、もう一度待ちます。クエリを実行すると、結果が利用できる場合があります。そうでない場合は、null が直接返されます。もちろん、再試行することもできます。もちろん、大規模な同時実行シナリオでは、それでもできることが望ましいです。結果を迅速に返し、再試行が多すぎることを避けます。
3. スケジュールされたタスクはホットスポット キーを更新します
これは簡単に理解できますが、端的に言えば、特定のホットスポット キーのタイムアウトを定期的に監視するスケジュールされたタスクです。有効期限が切れるかどうかに関係なく、有効期限が切れそうになったら、キャッシュ内のキーのキャッシュ時間を延長するだけです。
シングル スレッド ポーリング メソッドは、有効期限をチェックして更新します。図を参照してください:
マルチスレッド メソッド、ホットスポット キーが多すぎないように注意してください。特定のスレッドでは多くのホットスポット キーが開かれます。ホットスポット キーが多数ある場合は、スレッド プールを使用できます。図を参照してください:
遅延キューの実装
端的に言えば、シングルスレッドであろうとマルチスレッドであろうと、キーが有効かどうかを確認するためにポーリングが使用されます(毎回CPUを浪費します)。早い 期限切れです この方法では検査時間が不正確になり、時間の遅れや誤差が生じる可能性があります 次の検査を待っているときに鍵がなくなってしまい、その時点で故障が発生していることになります。 , この状況が発生する可能性は低いですが、実際に発生するので、どうすれば回避できますか? 実際、遅延キュー (リング キュー) を使用してそれを実現できます。このキューの原理については詳しく説明しません。ここにあります (Baidu または Google を使用できます)、いわゆる遅延キューは、設定した時間に従って消費されることを期待してこのキューにメッセージを送信するときに使用されます。時間が経過するまでは消費されません。時間が経過すると消費されます。それでは、画像を見て話しましょう:
1. 有効期限を取得するためにプログラムが初めて起動します。リスト内のキーの時刻。
2. キーの遅延消費時間を順に設定します (消費時間は有効期限よりも早いことに注意してください)。
3. キューの有効期限を遅らせると、コンシューマがキーを消費します。
4. コンシューマはメッセージを消費し、キャッシュへのキーの有効期限を遅らせます。
5. 新しいキーの有効期限を再度遅延キューに送信し、遅延キャッシュの次の有効期限を待ちます。
4. キーを無効化せずに設定する
実は、メモリ不足によりキーが削除される場合もあります。削除されました。
定義
いわゆるペネトレーションとは、キャッシュまたはキャッシュに存在しないキーにアクセスすることです。データベースにアクセスすると、この時点で DB に直接到達するトラフィックと同等になります。すると、一部の不正者がこの脆弱性を利用してインターフェイスを必死に荒らし、DB を破壊し、ビジネスが正常に実行できなくなります。
どうすれば解決できますか?
1. null または特別な値を設定する
null または特定の値を有効期限なしで redis に設定できるため、次回戻ってくることができます。 null または特別な値を redis から直接取得します。
この解決策では根本的な問題は解決できません。このトラフィックで役に立たないキーが大量に偽造される場合、どれだけ null や特殊な値を設定しても役に立ちません。では、どう解決すればよいでしょうか?
2. ブルームフィルター
ブルームフィルターは英語でbloomfilerといいますが、ここでは簡単に紹介します 紙面の都合上、別項とさせていただきますこの記事は紹介です。
たとえば、データベースに数千万の sku データが保存されている場合、現在の要件は、ライブラリにこの sku がある場合は redis をクエリし、redis がない場合はデータベースをクエリしてから redis を更新することです。 SKU データをハッシュマップに入れることが思い浮かびますが、キーは sku です。SKU が多いため、ハッシュマップは多くのメモリ領域を占有し、メモリがバーストする可能性があります。最終的には、ゲインが得られます。では、メモリを節約するにはどうすればよいでしょうか? ビット配列を使用してこの SKU の存在ステータスを保存できます。0 は存在しないことを表し、1 は存在を表します。ハッシュ関数を使用して SKU のハッシュ値を計算できます。次に、sku のハッシュ値をビット配列と比較します。モジュロを取得し、配列の位置を見つけて、それを 1 に設定します。リクエストが来ると、sku のハッシュ値に対応する配列の位置が 1 であるかどうかを計算します。 1の場合は存在することを意味し、0の場合は存在しないことを意味します。このような単純なブルームフィルターが実装されています。ブルームフィルターにはエラー率があります。精度を高めるために、配列の長さとハッシュ関数の数を増やすことを検討できます。具体的には、Baidu または Google を使用できます。今日はここでは説明しません。
ブルームファイラーを使用してキャッシュの侵入を防ぐプロセスを見てみましょう。絵を見て話しましょう:
ブルームファイラーの初期化では、スケジュールされたタスクを通じてデータベースを読み取り、ビット配列のサイズ、デフォルト値はすべて0で存在しないことを示し、項目ごとにハッシュ値に対応する配列位置を計算してビット配列に挿入します。
リクエスト プロセス、図を参照してください:
bloomfiler フィルターを使用しない場合、データベースに存在することが肝心ですが、実際には、Redis のクエリと DB のクエリの 2 つの IO が無駄になっていましたが、Bloomfiler を使用すると、これら 2 つの無駄な IO が節約され、バックエンド Redis と DB リソースの無駄が削減されます。
今日は、Redis キャッシュの高頻度のインタビューと実際の戦闘で遭遇した問題と解決策について話しました。
Cache Avalanche
解決策:
有効期限を設定するときに、ランダムな時間を追加すると、数分以内に完了します。
雪崩が発生した場合に何をすべきかという問題と同様に、電流制限を使用することもできます。
キャッシュの内訳
解決策:
電流制限
分散ロック
ホットスポット キーを定期的に更新します。ここでは遅延キューに焦点を当てます。
キャッシュの侵入
解決策:プログラミング入門! !
以上がRedis におけるキャッシュ雪崩、キャッシュのブレークダウン、キャッシュの侵入について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。