redis擊穿、雪崩問題

redis是開發(fā)中重度使用的中間件產品,在使用過程中踩過很多坑,遇到過擊穿,雪崩,穿透等多種場景, 對上述場景總結出如下使用經(jīng)驗

1 、擊穿
擊穿指的是單個key在緩存中查不到,去數(shù)據(jù)庫查詢,這樣如果數(shù)據(jù)量不大或者并發(fā)不大的話是沒有什么問題的。
如果數(shù)據(jù)庫數(shù)據(jù)量大并且是高并發(fā)的情況下那么就可能會造成數(shù)據(jù)庫壓力過大而崩潰.

方案:

   1、設置永久value ,在業(yè)務頂峰期定時去更新數(shù)據(jù),排隊刷新緩存。
   2、設置互斥鎖(mutex key)

比如,redis的SETNX 去set一個mutex key,當操作返回成功時,再進行l(wèi)oad db的操作并回設緩存;否則,就重試整個get緩存的方法。
3、將擊穿的key緩存起來,但是時間不能太長,下次進來是直接返回不存在,但是這種情況無法過濾掉動態(tài)的key,就是說每次請求進來都是不同額key,這樣還是會造成這個問題

public function test($key){
        $key_mutex = "key_mutex";
        $redis = new \Redis;
        $val = $redis->get($key);
        if($val == null){
            if($redis->setnx($key_mutex,"DB or function")){
                $redis->set($key,"DB or function");
                $redis->del($key_mutex);
                return "DB or function";
            }else{
                return $redis->get($key);
            }
        } else {
            return $val;
        }
 }

2、雪崩

雪崩指的是多個key查詢并且出現(xiàn)高并發(fā),緩存中失效或者查不到,然后都去db查詢,從而導致db壓力突然飆升,從而崩潰。

出現(xiàn)原因:

  1、key同時失效
  2、redis本身崩潰了

方案:
1、在緩存失效后,通過加鎖或者隊列來控制讀數(shù)據(jù)庫寫緩存的線程數(shù)量。比如對某個key只允許一個線程查詢數(shù)據(jù)和寫緩存,其他線程等待。

  2、在應用層面控制減少查詢的次數(shù)。
  3、可以通過緩存reload機制,預先去更新緩存,再即將發(fā)生大并發(fā)訪問前手動觸發(fā)加載緩存。
  4、不同的key,設置不同的過期時間,具體值可以根據(jù)業(yè)務決定,讓緩存失效的時間點盡量均勻做二級緩存,或者雙緩存策略。A1為原始緩存,A2為拷貝緩存,A1失效時,可以訪問A2,A1緩存失效時間設置為短期,A2設置為長期。(這種方式較復雜)

方案1和擊穿的第1個方案類似,但是這樣是避免不了其它key去查數(shù)據(jù)庫,只能通過方案2 減少查詢的次數(shù)。

    public static function sget($key, $obtainCacheDataFunc = NULL, $expiry = 0)
    {
        $redis = new \Redis;
        $cacheData = $redis->get($key);
        if ($redis->exists($key) == 0) {
//從二級緩存更新數(shù)據(jù)
            $cacheData = $redis->get("getSecondKey");
            if (is_callable($obtainCacheDataFunc)) {
                $lockGetCacheKey = "getTaskKey";
                if ($redis->set($lockGetCacheKey, 'key is exist?', 'ex', 60, 'nx')) {
                    $cacheData = serialize($obtainCacheDataFunc($key));
                    if (!$redis->set($key, $cacheData, 'ex', $expiry)) Log::write('redis_set_error');
                    $redis->set("getSecondKey", $cacheData, 'ex', $expiry + 3600);
                    $redis->del([$lockGetCacheKey]);
                }
            }
        }
        return unserialize($cacheData);
    }

3、穿透

一般是出現(xiàn)這種情況是,因為惡意頻繁查詢才會對系統(tǒng)造成很大的問題: key緩存并且數(shù)據(jù)庫不存在,所以每次查詢都會查詢數(shù)據(jù)庫從而導致數(shù)據(jù)庫崩潰。
布隆過濾器是什么?
布隆過濾器可以理解為一個不怎么精確的 set 結構,當你使用它的 contains 方法判斷某個對象是否存在時,它可能會誤判。但是布隆過濾器也不是特別不精確,只要參數(shù)設置的合理,它的精確度可以控制的相對足夠精確,只會有小小的誤判概率。
當布隆過濾器說某個值存在時,這個值可能不存在;當它說不存在時,那就肯定不存在。打個比方,當它說不認識你時,肯定就不認識;當它說見過你時,可能根本就沒見過面,不過因為你的臉跟它認識的人中某臉比較相似 (某些熟臉的系數(shù)組合),所以誤判以前見過你。
缺點:

 1、會存在一定的誤判率
 2、對新增加的數(shù)據(jù)無法進行布隆過濾
 3、數(shù)據(jù)的key不會頻繁的更改

 google的 gauva中有布隆過濾的實現(xiàn)

BloomFilter的關鍵在于hash算法的設定和bit數(shù)組的大小確定,通過權衡得到一個錯誤概率可以接受的結果。
我們設置的容錯率越小那么過濾函數(shù)也就多,分配的空間也就越大(存放bits),那么誤判率也就越小。

總結:其實關于redis擊穿,穿透,雪崩基本都是大同小異,但是想實現(xiàn)高并發(fā),高可用,高可靠的方案,還是要層層阻擋,從最前端的頁面,到ip的限制,到網(wǎng)關,再到業(yè)務過濾和緩存,最好盡可能的減少落到DB的數(shù)據(jù)量。才能全面保證應用程序的高并發(fā),高可用,高可靠。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370

推薦閱讀更多精彩內容