ホームページ >データベース >Redis >Redis キャッシュ雪崩問題を解決する方法

Redis キャッシュ雪崩問題を解決する方法

WBOY
WBOY転載
2023-06-03 09:46:021799ブラウズ

キャッシュ層は大量のリクエストを伝送し、ストレージ層を効果的に保護します。ただし、大量のキャッシュ障害によりストレージ層に大量のリクエストが到着したり、キャッシュ全体がサービスを提供できなくなったりすると、ストレージ層の負荷が増加します(大量のリクエストがデータベースにクエリを実行する)。これはキャッシュなだれのシナリオです。

キャッシュなだれを解決するには、次の点から始めることができます:

1. キャッシュ レイヤーの可用性を高く保つ

Redis を使用するセントリー モードまたは Redis クラスター デプロイメント方法では、個々の Redis ノードがオフラインになっても、キャッシュ レイヤー全体は引き続き使用できます。さらに、Redis は複数のコンピューター ルームにデプロイできるため、コンピューター ルームがクラッシュした場合でも、キャッシュ レイヤーの可用性を高めることができます。

2. 電流制限ダウングレード コンポーネント

キャッシュ層とストレージ層はどちらもエラーの可能性があり、リソースとみなすことができます。大量の同時実行性を持つ分散システムとして、リソースが使用できない場合、すべてのスレッドがこのリソースを取得するときに例外が発生し、システム全体が使用できなくなる可能性があります。同時実行性の高いシステムでは、ダウングレードは非常に一般的です。たとえば、レコメンデーション サービスでは、パーソナライズされたレコメンデーション サービスが利用できない場合、ダウングレードしてホットスポット データを補完し、レコメンデーション サービス全体が利用できなくなることを防ぐことができます。一般的な電流制限劣化コンポーネントには、Hystrix、Sentinel などが含まれます。

3. キャッシュは期限切れになりません

Redis に保存されたキーは期限切れにならないため、多数のキャッシュが同時に失敗するという問題は発生しませんが、その場合、Redis にはより多くのストレージ。

4. キャッシュの有効期限を最適化する

キャッシュを設計するときは、多数のキーが同時に無効になり、キャッシュなだれが発生するのを避けるために、各キーに適切な有効期限を選択します。

5. ミューテックス ロックを使用してキャッシュを再構築する

高同時実行シナリオでは、データのクエリとキャッシュの再構築を同時に行うためにストレージ レイヤーに大量のリクエストが到達するのを避けるために、 「キーはデータをクエリするためにキャッシュ レイヤーに移動します。キャッシュ レイヤーがヒットすると、キーはロックされ、データはストレージ レイヤーからクエリされ、データはストレージ レイヤーに書き込まれます。」のように、ミューテックス ロック制御を使用できます。キャッシュ層にアクセスし、最終的にロックが解放されます。他のスレッドがロックの取得に失敗したことを検出した場合は、スレッドを一定期間スリープさせて再試行します。ロックの種類については、スタンドアロン環境の場合はJavaコンカレントパッケージのLockを、分散環境の場合は分散ロック(RedisのSETNXメソッド)を使用できます。

分散環境におけるミューテックスロック再構築キャッシュ擬似コード

/**
 * 互斥锁建立缓存
 *
 **/
public String get(String key) {
   // redis中查询key对应的value
   String value = redis.get(key);
   // 缓存未命中
   if (value == null) {
      // 互斥锁
      String key_mutex_lock = "mutex:lock" + key; 
      // 互斥锁加锁成功
      if(redis.setnx(key_mutex_lock,"1")) { // 返回 0(false),1(true)
          try {
              // 设置互斥锁超时时间,这里设置的是锁的失效时间,而不是key的失效时间
              redis.expire(key_mutex_lock,3*60);
              // 从数据库查询
              value = db.get(key);
              // 数据写入缓存
              redis.set(key,value);
            
          } finally {
               // 释放锁
              boolean keyExist = jedis.exists(key_mutex_lock);
              if(keyExist){
                  redis.delete(key_mutex_lock);
               }
      } else { 
              // 加锁失败,线程休息50ms后重试
               Thread.sleep(50);
               return get(key); // 直接返回缓存结果  
     }
   }
}

Redis 分散ロックは、分散環境におけるキャッシュ再構築の実装に使用され、設計思想がシンプルでデータの整合性が保証されるという利点があります。 ; デメリットは、コードの複雑さが増し、ユーザーが待たされる可能性があることです。高い同時実行性では、キャッシュの再構築中にキーがロックされると仮定します。現在 1,000 個の同時リクエストがある場合、そのうち 999 個がブロックされ、999 個のユーザー リクエストがブロックされて待機することになります。

6. キャッシュの非同期再構築

このスキームでは、キャッシュの構築に非同期戦略が採用されており、スレッド プールからスレッドを取得して非同期にキャッシュを構築します。リクエストはストレージに直接到達しません。レイヤー、このソリューションの各 Redis キーは論理タイムアウトを維持します。論理タイムアウトが現在時刻より小さい場合、現在のキャッシュの有効期限が切れているため、キャッシュを更新する必要があることを意味します。それ以外の場合は、キャッシュを更新する必要があります。現在のキャッシュの有効期限が切れておらず、キャッシュ内の値が直接返されることを意味します。たとえば、Redis では、キーの有効期限は 60 分に設定され、対応する値の論理有効期限は 30 分に設定されます。このようにして、キーが論理有効期限の 30 分に達すると、このキーのキャッシュを非同期で更新できますが、キャッシュの更新期間中は古いキャッシュが引き続き使用できます。この非同期キャッシュ再構築方法により、多数のキーが同時に無効になることを効果的に防ぐことができます。

rree

以上がRedis キャッシュ雪崩問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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