インタビューRedis-キャッシュコンカレントキャッシュアバランシェキャッシュペネトレーション

この記事では、主に、キャッシュの同時実行性、キャッシュのアバランシェ、およびキャッシュの侵入に関する問題と解決策について説明します。

キャッシュの並行性

キャッシュの同時実行性とは

シナリオ:毎日Douyinを使用してWeChatの短いビデオを見ると、コメントのリストが表示されます。コメントのリストには、コメントをクエリするときに、最初にRedisキャッシュをクエリします。ある場合はすぐに戻ります。ない場合はすぐに戻ります。 goデータベースはデータをクエリし、キャッシュを更新してデータを返します。現時点では、訪問数が多い場合、同時にコメントをクエリする複数のC側があり、Redisキャッシュはたまたまデータをキャッシュしません。このとき、複数のC側が同時にデータベースにクエリを実行します。時間。上記の現象は、キャッシュの同時実行性と呼ばれます。

キャッシュヒット

ミスキャッシュ

そうは言っても、並行性をキャッシュすることによってどのような害が生じるのでしょうか。

  • データベースは高い同時実行性に耐えられず、トラフィックが多いと直接破壊される可能性があるため、データベースへの圧力が急激に高まっています。ユーザーにとって非常に不親切です。最近のインターネットでは、アプリアプリケーションの交換率は非常に高くなっています。高く、少し不注意で、ユーザーは他のアプリに奪われてしまい、企業にとって悲惨なことになります。Redisは物であるか、問題がないかを知ることができます。問題がある場合、それは大きな問題であるに違いありません。そのため、理由を知ることを強調する必要があります。

キャッシュの同時実行性の重大度がわかったので、それを解決する方法

  • 問題を解決する前に、問題が発生した理由を分析する必要があります。話をすると、面接中や職場で問題が発生した場合でも、すぐに変更したり、Baiduの方法で試してみたりする人が多いのですが、うまくいきません。問題を解決するこの方法は正しくありません。一般的な問題解決の方法論は次のとおりです。エラーが発生した-問題を特定する-問題を分析する-解決策を設計する-問題を解決する。キャッシュの同時実行性の問題に戻り、「キャッシュの同時実行性が発生する理由」を分析してみましょう。

並行性をキャッシュする理由

  • 理由1:同時実行性の高いシナリオでは、マシンが起動したばかりで、キャッシュがウォームアップされておらず、キャッシュが空であり、分散ロックが使用されていません。
  • 理由2:同時実行性の高いシナリオでは、マシンは一定期間実行されていますが、キャッシュに障害が発生し、分散ロックが役に立たない
  • 理由3:同時実行性の高いシナリオでRedisがダウンしている

上記の3つの理由により、キャッシュの同時実行が発生します。他の理由を省略した場合は、メッセージ領域に追加してください。

理由を知った後、その理由に対する解決策を設計することができます。

解決

  • 理由1と2の理由で、解決策は分散ロックです。これにより、1つのスレッドがデータベースを要求し、他のスレッドがハングアップすることができます。スレッドがデータベースをチェックした後、キャッシュを更新し、他のスレッドがキャッシュにアクセスしてデータを返します。分散ロックの使用方法とその基礎となる実装については、実際には注意が必要な詳細がありますが、ここで説明する必要はありません。対応する記事がフォローアップで公開されます。我慢できない場合孤独、あなたはグーグルに行くことができます。

  • 3番目の理由で、プログラム:Redisの高可用性。高可用性に関して言えば、それはマスタースレーブ構造+センチネルモード、またはRedisクラスターにすぎません。(リンクを追加)

分散ロックとRedisの高可用性は、実際には予防策です。これらは事前作業である必要があります。キャッシュの同時実行が実際に発生した場合は、このモジュールサービスのトラフィックが過剰になり、他のモジュールサービスが影響を受けるため、MySQLを直接強制終了しないように、このモジュールサービスのトラフィックエントリを減らすことができます。 。Redisがダウンしている場合は、最初にトラフィックエントランスを減らしてから、マシンをすばやく再起動します。

もちろん、Hystrixの電流制限、ダウングレード、およびサービス拒否を事前に適切に行うことが最善です。電流制限とダウングレード、電流制限は、その名前が示すように、フローを制限することです。たとえば、1秒あたり最大1000のトラフィックを通過させることができます。1000を超えるリクエストはダウングレードされます。たとえば、いくつかのデフォルト値を返すか、わかりやすいリマインダーです。システムは現在ビジーです。しばらくしてからもう一度お試しください。サービス拒否は最後の防衛線です。一定期間経ってもトラフィックが多い場合は、サービスを直接拒否します。サービス拒否は、Redisがトラフィックに流されないように保護するためのものです。Redisサービスが殺された場合、回復がより重要になります。これには時間がかかり、トラフィックが大きく、再起動したばかりであるため、トラフィックの波がRedisを直接奪い、ダブルキルであるダブルキルを完了しました。サービス拒否攻撃は、トラフィックが少なくなった後、より早く通常のサービス状態に戻ります。サービス拒否は最後の手段です。

kohlrabiが最初にインターネット業界に参入したとき、私はそれについて何も知りませんでした。Redisを使用する前は、Redisが非常に強力で、キャッシュに適していることだけを知っていました。Redisについては、keys *コマンドを使用できないことを除いて注意してください。実稼働環境、その他すべて理解できません。当時のレビュープロジェクトでは、トラフィックが非常に多く、同時実行性が高いため、クエリコメントインターフェイスにキャッシュの同時実行性の問題がありました。幸い、デフォルト値の応答と現在の制限+ダウングレード対策が事前に行われていました。以下は、分散ロックを使用してキャッシュの同時実行性を解決するためのキーコードです。

  @Autowired
  private DistributionLock locker;
  
 //没缓存,查数据库,获取评论
  if (comment == null) {
      //加分布式锁,只允许一个线程去回源
      if(locker.trylock(Constants.QUERYCOMMENT+moduleType+resourceId)){
          try {
              comment = getDataFromRedis(moduleType, resourceId);
              if(comment == null){
                  //缓存没数据,去数据库查
                  comment = getDataFromMongoDB(moduleType, resourceId);
              }
          }finally {
              locker.unlock(Constants.QUERYCOMMENT+moduleType+resourceId);
          }
      }

分散ロック

次に、キャッシュの浸透について話し続けます

キャッシュの浸透

キャッシュペネトレーションとは

シナリオ:コメントをクエリするときに、id = -1のデータが直接クエリされると、キャッシュが失われ、データベースに移動して検索されますが、失敗します。上記の状況は、キャッシュペネトレーションと呼ばれます。わかりやすくわかりやすい言葉でまとめると、データベースに存在してはならないデータを見つけることをキャッシュペネトレーションと呼びます。

キャッシュペネトレーションのデメリットは何ですか?

  • トラフィックが多い場合、サービスは直接使用され、サービスを利用できなくなります。

方法論に従い続けます

キャッシュの侵入が発生する理由

  • 最初の理由は、ハッカー攻撃などの異常な要求が、要求する特別な形式のデータを特別に構築し、システムに大きな圧力をかけることです。

  • 2つ目の理由は、ユーザーが通常のリクエストで間違ったデータを入力したことです。

解決

  • 解決策1:空のオブジェクトをキャッシュする:要求するとき、最初にキャッシュにアクセスしますが、データが見つかりません。次にデータベースに移動してクエリを実行すると、データベースは対応するデータを見つけることができず、クライアントにnullを返します。そして、キャッシュを非同期的に更新し(キー、「null」)、短い有効期限を追加します。
    空のオブジェクトをキャッシュする

  • 解決策2:解決策1には、実際には明らかな欠点があります。つまり、要求されたデータが存在してはならない場合、この時点で、キャッシュは多くの役に立たない(key1、 "null")、(key2、 "null")をキャッシュします。 。記憶の浪費。このとき、データチェックサムとブルームフィルターを組み合わせることができます。
    ブルームフィルター

データ検証に関しては、この問題は特に重要です。特にお金を直接伴う一部のサービスでは、データの検証が非常に重要です。データ検証がなければ、大企業の上司はベントレーを1つ失うことになります。中小企業は直接破産する可能性があります。以下はルタバガの学生の会社の場合です
ケース1
ケース2

いずれにせよ、良い開発習慣を身につけることはあなたに一生の利益をもたらすことができます。

キャッシュアバランシェ

キャッシュアバランシェとは

シナリオ:コメントリストで、コメントのバッチがホットコメントになった場合、残念ながら、このコメントのバッチは現時点ではRedisキャッシュでは無効です。キャッシュが失われ、多数のリクエストが追加されるため、すべてのコメントはデータベースに送られ、コメントを照会します。したがって、データベースに大きなプレッシャーがかかるか、クラッシュすることさえあります。この状況は、キャッシュアバランシェと呼ばれます。
キャッシュアバランシェ

キャッシュアバランシェのデメリット

それはデータベースに大きな圧力をかけ、さらにはデータベースを破壊し、システムが正常にサービスを提供できなくなる原因になります。

雪崩をキャッシュする理由

  • 理由1:Redisがダウンしています。これは、複数のキーが同時に失敗するのと同じです。

  • 2番目の理由は、redisがダウンしておらず、複数のキーが正常に到着すると失敗することです。

概要:インタビュー中にこの質問に遭遇した場合は、個別に回答することをお勧めします。つまり、redisがダウンしているかどうかです。インタビュアーに明確な印象を与えます。

解決

  • 解決策1、理由1を解決します。マシンがダウンしているため、高可用性、redisクラスター、センチネルモード、フェイルオーバーと障害回復を検討し、監視とアラームも行う必要があります。フェイルオーバーを自動的に完了できない場合は、手動で介入します。

  • 解決策2、有効期限=有効期限+ランダム時間、原因2を解決します。

  • オプション3、有効期限はありません。有効期限が原因で雪崩が発生するため、有効期限なしで実行します。キャッシュの一貫性を確保する方法を尋ねる人もいるかもしれません。アクティブなバックグラウンド更新:mysqlを介して更新する場合、mqにBinlogをリッスンさせ、コールバックしてキャッシュを更新します。キャッシュとデータベースデータの一貫性を保ちます。

  • ソリューション4は、アプリケーションアーキテクチャの観点から、この災害を回避するためにマルチレベルキャッシュを回避することに加えて、電流制限、劣化、および融合によって影響を軽減できます。使用しているマイクロサービスアーキテクチャがSpringCloudの場合、Hystrixを直接使用して、電流制限、ダウングレード、融合を実現し、構成ファイルを変更するだけです。

補足

キャッシュの内訳は、1つのキーのみが期限切れになるキャッシュアバランシェです。

総括する

記事全体を通して、ほとんどすべてがエラーの報告-問題の位置付け-問題の分析-解決策の設計-問題の解決の方法論に従って書かれています。この記事では、キャッシュの同時実行性、キャッシュの浸透、およびキャッシュのなだれの定義、危険性、原因、および解決策を紹介します。Rutabagaは、この記事を読んだ後、知識を学ぶだけでなく、問題の位置付け、問題の分析、問題の解決の方法論を習得することを望んでいます。知識のポイント、これらは将来忘れられるかもしれませんが、メソッドが習得された後、あなたはトリックを見ることができます。

これを見ていただきありがとうございます。記事がうまく書かれていると思われる場合は、それに注意を払い、共有してください(私にとって非常に便利です)。
記事を改善する必要があるとお考えの場合は、ご提案をお待ちしております。メッセージを残してください。
あなたが何かを見たいのなら、私はあなたのメッセージを楽しみにしています。
あなたのサポートとサポートは私の創造の最大の動機です!

おすすめ

転載: blog.csdn.net/Aaron_Tang_/article/details/114670135