亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長(zhǎng)資訊網(wǎng)
    最全最豐富的資訊網(wǎng)站

    一起學(xué)習(xí) Redis緩存穿透、緩存擊穿、緩存雪崩的原理和解決辦法

    一起學(xué)習(xí) Redis緩存穿透、緩存擊穿、緩存雪崩的原理和解決辦法

    推薦(免費(fèi)):redis

    • 緩存穿透:key中對(duì)應(yīng)的緩存數(shù)據(jù)不存在,導(dǎo)致去請(qǐng)求數(shù)據(jù)庫(kù),造成數(shù)據(jù)庫(kù)的壓力倍增的情況

    • 緩存擊穿:redis過(guò)期后的一瞬間,有大量用戶請(qǐng)求同一個(gè)緩存數(shù)據(jù),導(dǎo)致這些請(qǐng)求都去請(qǐng)求數(shù)據(jù)庫(kù),造成數(shù)據(jù)庫(kù)壓力倍增的情,針對(duì)一個(gè)key而言

    • 緩存雪崩:緩存服務(wù)器宕機(jī)或者大量緩存集中某個(gè)時(shí)間段失效,導(dǎo)致請(qǐng)求全部去到數(shù)據(jù)庫(kù),造成數(shù)據(jù)庫(kù)壓力倍增的情況,這個(gè)是針對(duì)多個(gè)key而言

    一、緩存穿透的解決方案

    • 常用方法可以采用布隆過(guò)濾器方法進(jìn)行數(shù)據(jù)攔截,其次可以還有一種解決思路,就是如果請(qǐng)求的數(shù)據(jù)為空,將空值也進(jìn)行緩存,就不會(huì)發(fā)生穿透情況
    <?php class getPrizeList {     /**      * redis實(shí)例      * @var Redis      */     private $redis;      /**      * @var string      */     private $redis_key = '|prize_list';      /**      * 過(guò)期時(shí)間      * @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)) {             //此處應(yīng)該進(jìn)行數(shù)據(jù)庫(kù)查詢...             //如果查詢結(jié)果不存在,給其默認(rèn)空數(shù)組進(jìn)行緩存             $result = [];             $this->redis->set($this->redis_key, $result, $this->expire);         }          return $result;     } }

    二、緩存擊穿解決辦法

    • 使用互斥鎖(mutex key),就是一個(gè)key過(guò)期時(shí),多個(gè)請(qǐng)求過(guò)來(lái)允許其中一個(gè)請(qǐng)求去操作數(shù)據(jù)庫(kù),其他請(qǐng)求等待第一個(gè)請(qǐng)求成功返回結(jié)果后再請(qǐng)求。
    <?php class getPrizeList {     /**      * redis實(shí)例      * @var Redis      */     private $redis;      /**      * @var string      */     private $redis_key = '|prize_list';      /**      * @var string      */     private $setnx_key = '|prize_list_setnx';      /**      * 過(guò)期時(shí)間      * @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)) {                 //此處應(yīng)該進(jìn)行數(shù)據(jù)庫(kù)查詢...                 //$result = 數(shù)據(jù)庫(kù)查詢結(jié)果;                 $this->redis->set($this->redis_key, $result, $this->expire);                 $this->redis->del($this->setnx_key); //刪除互斥鎖             } else {                 //其他請(qǐng)求每等待10毫秒重新請(qǐng)求一次                 sleep(10);                 self::fetch();             }         }          return $result;     } }

    三、緩存雪崩的解決辦法

    • 這種情況是因?yàn)槎鄠€(gè)key同時(shí)過(guò)期導(dǎo)致的數(shù)據(jù)庫(kù)壓力,一種方法可以在key過(guò)期時(shí)間基礎(chǔ)上增加時(shí)間隨機(jī)數(shù),讓過(guò)期時(shí)間分散開(kāi),減少緩存時(shí)間過(guò)期的重復(fù)率
    • 另一種方法就是加鎖排隊(duì),這種有點(diǎn)像上面緩存擊穿的解決方式,但是這種請(qǐng)求量太大,比如5000個(gè)請(qǐng)求過(guò)來(lái),4999個(gè)都需要等待,這必然是指標(biāo)不治本,不僅用戶體驗(yàn)性差,分布式環(huán)境下就更加復(fù)雜,因此在高并發(fā)場(chǎng)景下很少使用
    • 最好的解決方法,是使用緩存標(biāo)記,判斷該標(biāo)記是否過(guò)期,過(guò)期則去請(qǐng)求數(shù)據(jù)庫(kù),而緩存數(shù)據(jù)的過(guò)期時(shí)間要設(shè)置的比緩存標(biāo)記的長(zhǎng),這樣當(dāng)一個(gè)請(qǐng)求去操作數(shù)據(jù)庫(kù)的時(shí)候,其他請(qǐng)求拿的是上一次緩存數(shù)據(jù)
    <?php class getPrizeList {     /**      * redis實(shí)例      * @var Redis      */     private $redis;      /**      * @var string      */     private $redis_key = '|prize_list';      /**      * 緩存標(biāo)記key      * @var string      */     private $cash_key = '|prize_list_cash';      /**      * 過(guò)期時(shí)間      * @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);             //此處應(yīng)該進(jìn)行數(shù)據(jù)庫(kù)查詢...             //$result = 數(shù)據(jù)庫(kù)查詢結(jié)果, 并且設(shè)置的時(shí)間要比cash_key長(zhǎng),這里設(shè)置為2倍;             $this->redis->set($this->redis_key, $result, $this->expire * 2);         }          return $result;     } }

    贊(0)
    分享到: 更多 (0)
    網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)