キャッシュアバランシェ
- キャッシュアバランシェとは何ですか?
キャッシュアバランシェは、同時にキャッシュ障害の広い領域を指します。そのため、後続のリクエストはデータベースに分類され、データベースは短期間に多数のリクエストに耐えてクラッシュします。 - 解決
- キャッシュされたデータの有効期限は、大量のデータが同時に期限切れになるのを防ぐためにランダムに設定されます。
- 一般に、並行性の量が特に高くない場合、最もよく使用される解決策は、ロックしてキューに入れることです。
偽のコード:/* 注意:加锁排队只是为了减轻数据库的压力,并没有提高系统吞吐量。 假设在高并发下,缓存重建期间key是锁着的,这是过来1000个请求999个都在阻塞的。 同样会导致用户等待超时,这是个治标不治本的方法! 加锁排队的解决方式分布式环境的并发问题,有可能还要解决分布式锁的问题; 线程还会被阻塞,用户体验很差!因此,在真正的高并发场景下很少使用! */ //伪代码 public object GetProductListNew() { int cacheTime = 30; String cacheKey = "product_list"; String lockKey = cacheKey; String cacheValue = CacheHelper.get(cacheKey); if (cacheValue != null) { return cacheValue; } else { synchronized(lockKey) { cacheValue = CacheHelper.get(cacheKey); if (cacheValue != null) { return cacheValue; } else { //这里一般是sql查询数据 cacheValue = GetProductListFromDB(); CacheHelper.Add(cacheKey, cacheValue, cacheTime); } } return cacheValue; } }
- キャッシュされた各データに対応するキャッシュマークを追加し、キャッシュが無効かどうかを記録します。キャッシュマークが無効な場合は、データキャッシュを更新します。
偽のコード:/* 解释说明: 1、缓存标记:记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去更新实际key的缓存; 2、缓存数据:它的过期时间比缓存标记的时间延长1倍,例:标记缓存时间30分钟,数据缓存设置为60分钟。 这样,当缓存标记key过期后,实际缓存还能把旧数据返回给调用端,直到另外的线程在后台更新完成后,才会返回新缓存。 关于缓存崩溃的解决方法,这里提出了三种方案: 使用锁或队列、设置过期标志更新缓存、 为key设置不同的缓存失效时间, 还有一各被称为“二级缓存”的解决方法,有兴趣的读者可以自行研究。 */ //伪代码 public object GetProductListNew() { int cacheTime = 30; String cacheKey = "product_list"; //缓存标记 String cacheSign = cacheKey + "_sign"; String sign = CacheHelper.Get(cacheSign); //获取缓存值 String cacheValue = CacheHelper.Get(cacheKey); if (sign != null) { return cacheValue; //未过期,直接返回 } else { CacheHelper.Add(cacheSign, "1", cacheTime); ThreadPool.QueueUserWorkItem((arg) -> { //这里一般是 sql查询数据 cacheValue = GetProductListFromDB(); //日期设缓存时间的2倍,用于脏读 CacheHelper.Add(cacheKey, cacheValue, cacheTime * 2); }); return cacheValue; } }
キャッシュの浸透
- キャッシュペネトレーションとは何ですか?
キャッシュペネトレーションとは、キャッシュまたはデータベースにないデータを指し、すべてのリクエストがデータベースに分類され、短期間に多数のリクエストが発生したためにデータベースがクラッシュします。 - 解決
- インターフェイス層は、ユーザー認証検証などの検証を追加し、idは基本的な検証に使用され、id <= 0は直接インターセプトされます。
- キャッシュから取得できないデータもデータベースに取得されません。このとき、キーと値のペアをキーヌルとして書き込むこともでき、キャッシュの有効時間を30などに短く設定できます。秒(設定が長すぎると通常の状態になります使用できません)。これにより、攻撃するユーザーが同じIDブルートフォース攻撃を繰り返し使用するのを防ぐことができます。
- ブルームフィルターを使用して、すべての可能なデータを十分な大きさのビットマップにハッシュします。存在してはならないデータはこのビットマップによってインターセプトされるため、基盤となるストレージシステムへのクエリのプレッシャーを回避できます。
キャッシュの内訳
- キャッシュの内訳とは何ですか?
キャッシュの内訳とは、キャッシュではなくデータベースにあるデータを指します(通常はキャッシュ時間が経過するため)。現時点では、同時ユーザーが非常に多く、データが同時にキャッシュを読み取ると、データベースに移動してデータを取得します。これにより、データベースの圧力が即座に増加し、過度の圧力が発生します。キャッシュアバランシェとは異なり、キャッシュブレイクダウンとは、同じデータを同時にチェックすることです。キャッシュアバランシェとは、異なるデータの有効期限が切れており、多くのデータが見つからないため、データベースをチェックできます。 - 解決
- ホットスポットデータが期限切れにならないように設定します。
- ミューテックスを追加
キャッシュのウォームアップ
- キャッシュウォームアップとは何ですか?
キャッシュウォームアップとは、システムがオンラインになった後、関連するキャッシュデータがキャッシュシステムに直接ロードされることを意味します。このようにして、最初にデータベースにクエリを実行し、ユーザーが要求したときにデータをキャッシュするという問題を回避できます。ユーザーは、予熱されたキャッシュデータを直接クエリします。 - 解決
- キャッシュを作成してページを直接更新し、オンラインになったときに手動で更新します。
- データ量は多くなく、プロジェクトの開始時に自動的にロードできます。
- キャッシュを定期的に更新します。
キャッシュの劣化
https://www.iteye.com/blog/1181731633-2370315
トラフィックが急激に増加した場合、サービスに問題がある場合(応答時間が遅い、応答しないなど)、またはコア以外のサービスがコアプロセスのパフォーマンスに影響を与える場合は、サービスが引き続き利用可能であることを確認する必要があります。サービスに有害です。システムは、いくつかの重要なデータに基づいて自動的に劣化する可能性があります。または、手動で劣化するようにスイッチを使用して構成することもできます。
キャッシュ劣化の最終的な目標は、損失が発生した場合でもコアサービスを確実に利用できるようにすることです。また、一部のサービスはダウングレードできません(ショッピングカートへの追加、決済など)。
ダウングレードする前に、システムを整理して、システムがポーンを失い、司令官を保護できるかどうかを確認する必要があります。したがって、保護する必要があるものとダウングレードできるものを整理する必要があります。たとえば、ログレベル設定プランを参照できます。
- 一般:たとえば、一部のサービスは、ネットワークジッターが原因でタイムアウトしたり、サービスがオンラインになっている場合があり、自動的に低下する可能性があります。
- 警告:一部のサービスは、一定期間内(たとえば、95%から100%の間)に成功率が変動し、自動または手動で低下する可能性があり、アラームが送信されます。
- エラー:たとえば、可用性率が90%未満であるか、データベース接続プールがバーストされているか、トラフィックがシステムが耐えられる最大しきい値まで突然増加します。この時点で、トラフィックは自動的にダウングレードされるか、手動でダウングレードされます。状況に;
- 重大なエラー:たとえば、特別な理由でデータが間違っているため、現時点では緊急の手動ダウングレードが必要です。
サービスのダウングレードの目的は、データベースでアバランシェの問題が発生するRedisサービスの障害を防ぐことです。したがって、重要でないキャッシュデータの場合、サービス低下戦略を採用できます。たとえば、Redisはデータベースにクエリを実行せず、デフォルト値をユーザーに直接返すという一般的な方法があります。
ホットデータとコールドデータ
https://www.jianshu.com/p/053ba529bf02
ホットキーをキャッシュする
キャッシュ内のキー(販促アイテムなど)は、特定の時点で期限切れになると、その時点でこのキーに対する多数の同時リクエストが発生します。これらのリクエストは通常、バックからデータをロードします。キャッシュの有効期限が切れたらDBを終了します。キャッシュに戻します。このとき、大きな同時リクエストがすぐにバックエンドDBを圧倒する可能性があります。
解決
キャッシュクエリをロックします。KEYが存在しない場合はロックし、DBをキャッシュにチェックインしてからロックを解除します。他のプロセスがロックを見つけた場合は、待機してから、ロック解除がデータを返すか、 DBクエリ