ホームページ  >  記事  >  データベース  >  Redis キャッシュの侵入、キャッシュの破壊、キャッシュなだれの原理と解決策を一緒に学びましょう

Redis キャッシュの侵入、キャッシュの破壊、キャッシュなだれの原理と解決策を一緒に学びましょう

coldplay.xixi
coldplay.xixi転載
2021-01-28 18:13:132347ブラウズ

Redis キャッシュの侵入、キャッシュの破壊、キャッシュなだれの原理と解決策を一緒に学びましょう

推奨 (無料): redis

  • キャッシュの侵入:キー内の対応するキャッシュ データが存在しないため、データベースが要求され、データベースへの負荷が 2 倍になります。

  • キャッシュの内訳: One Redis の有効期限が切れると、すぐに多数のユーザーが同じキャッシュ データをリクエストし、これらのリクエストがデータベースをリクエストすることになり、データベースへの負荷が 2 倍になります。 ## キャッシュ雪崩:

    キャッシュ サーバーがダウンしているか、一定期間に大量のキャッシュが集中しているため、すべてのリクエストがデータベースに送信され、データベースの負荷が 2 倍になります。これは複数のキーに対するものです
  • 1. キャッシュ侵入の解決策

一般的に使用される方法では、ブルーム フィルター メソッドを使用してデータを傍受できます。別の解決策があります。つまり、リクエストのデータが空で、空の値もキャッシュされるため、侵入は発生しません。

    <?php
    class getPrizeList {
        /**
         * redis实例
         * @var \Redis
         */
        private $redis;
    
        /**
         * @var string
         */
        private $redis_key = &#39;|prize_list&#39;;
    
        /**
         * 过期时间
         * @var int
         */
        private $expire = 30;
    
        /**
         * getPrizeList constructor.
         * @param $redis
         */
        public function __construct($redis)
        {
            $this->redis = $redis;
        }
    
        /**
         * @return array|bool|string
         */
        public function fetch()
        {
            $result = $this->redis->get($this->redis_key);
            if(!isset($result)) {
                //此处应该进行数据库查询...
                //如果查询结果不存在,给其默认空数组进行缓存
                $result = [];
                $this->redis->set($this->redis_key, $result, $this->expire);
            }
    
            return $result;
        }
    }
  • 2.キャッシュブレイクダウンソリューション
  • ミューテックスキーを使用すると、キーの有効期限が切れると、複数のリクエストが来て、そのうちの 1 つがデータベースを操作できるようになり、他のリクエストは最初のリクエストを待つことになります。再度リクエストする前に、結果が正常に返されるようにリクエストしてください。

      <?php
      class getPrizeList {
          /**
           * redis实例
           * @var \Redis
           */
          private $redis;
      
          /**
           * @var string
           */
          private $redis_key = &#39;|prize_list&#39;;
      
          /**
           * @var string
           */
          private $setnx_key = &#39;|prize_list_setnx&#39;;
      
          /**
           * 过期时间
           * @var int
           */
          private $expire = 30;
      
          /**
           * getPrizeList constructor.
           * @param $redis
           */
          public function __construct($redis)
          {
              $this->redis = $redis;
          }
      
          /**
           * @return array|bool|string
           */
          public function fetch()
          {
              $result = $this->redis->get($this->redis_key);
              if(!isset($result)) {
                  if($this->redis->setnx($this->setnx_key, 1, $this->expire)) {
                      //此处应该进行数据库查询...
                      //$result = 数据库查询结果;
                      $this->redis->set($this->redis_key, $result, $this->expire);
                      $this->redis->del($this->setnx_key); //删除互斥锁
                  } else {
                      //其他请求每等待10毫秒重新请求一次
                      sleep(10);
                      self::fetch();
                  }
              }
      
              return $result;
          }
      }
    • 3. キャッシュ雪崩の解決策
    • この状況は、複数のキーが同時に期限切れになることが原因で発生します。データベースのプレッシャー。1 つの方法として、キーの有効期限に基づいて時間乱数を追加して、有効期限を分散し、キャッシュ時間の有効期限の繰り返し率を減らすことができます。 ##もう 1 つの方法は、ロックすることです。キューイングは、上記のキャッシュ ブレークダウンの解決策に少し似ていますが、リクエストの量が多すぎます。たとえば、5,000 件のリクエストが受信され、4,999 件のリクエストが待機する必要があります。これは、次のことを示す指標である必要があります。根本的な原因は解決されません。ユーザー エクスペリエンスが劣悪であるだけでなく、分散環境でも問題が発生します。より複雑なため、同時実行性の高いシナリオではほとんど使用されません。

      • 最良の方法解決策は、キャッシュ タグを使用して、タグの有効期限が切れているかどうかを判断することです。有効期限が切れた場合は、データベースにリクエストしてキャッシュします。データの有効期限は、キャッシュ マークよりも長く設定する必要があります。データベース、他のリクエストは最後にキャッシュされたデータを取得します
      <?php
      class getPrizeList {
          /**
           * redis实例
           * @var \Redis
           */
          private $redis;
      
          /**
           * @var string
           */
          private $redis_key = &#39;|prize_list&#39;;
      
          /**
           * 缓存标记key
           * @var string
           */
          private $cash_key = &#39;|prize_list_cash&#39;;
      
          /**
           * 过期时间
           * @var int
           */
          private $expire = 30;
      
          /**
           * getPrizeList constructor.
           * @param $redis
           */
          public function __construct($redis)
          {
              $this->redis = $redis;
          }
      
          /**
           * @return array|bool|string
           */
          public function fetch()
          {
              $cash_result = $this->redis->get($this->cash_key);
              $result = $this->redis->get($this->redis_key);
              if(!$cash_result) {
                  $this->redis->set($this->cash_key, 1, $this->expire);
                  //此处应该进行数据库查询...
                  //$result = 数据库查询结果, 并且设置的时间要比cash_key长,这里设置为2倍;
                  $this->redis->set($this->redis_key, $result, $this->expire * 2);
              }
      
              return $result;
          }
      }

      以上がRedis キャッシュの侵入、キャッシュの破壊、キャッシュなだれの原理と解決策を一緒に学びましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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