在互聯(lián)網時代,大流量、海量數(shù)據(jù)、高并發(fā)是每個企業(yè)都渴望又害怕的名詞,渴望是因為它們代表著提供的服務用戶愿意買單、有價值;害怕是因為一旦用戶全上來了,系統(tǒng)不能正常為用戶提供服務,讓用戶失望,最終選擇離開。僅靠著超高配置的服務器資源,還是很難支撐高并發(fā)的場景。因此我們需要緩存。
緩存在計算機的世界里無處不在,在CPU中有一級二級三級緩存,在Linux操作心態(tài)中有TLB加速虛擬地址和物理地址的轉化,在應用服務中有redis數(shù)據(jù)庫進行數(shù)據(jù)緩存,在瀏覽器或app中有本地緩存。可以說緩存是非常重要了,有了它,整個世界仿佛都變美好了,刷網頁很快就有數(shù)據(jù)的返回,再也不用一直苦苦等待了。
通過一個簡單的例子來看看緩存是什么?我們知道數(shù)據(jù)都是存儲在數(shù)據(jù)庫里的,而數(shù)據(jù)庫數(shù)據(jù)一般都存儲在磁盤上。當用戶請求從前端過來時,如果直接去訪問獲取磁盤的數(shù)據(jù)庫數(shù)據(jù),就會非常慢。如果有了緩存,在用戶請求到達之后,業(yè)務線程就會先訪問緩存,如果緩存命中就直接返回用戶,如果沒有命中,則繼續(xù)請求磁盤數(shù)據(jù)庫數(shù)據(jù),獲取后返回用戶,同時將磁盤獲取的數(shù)據(jù)結果回寫到緩存系統(tǒng),為下次請求做好準備。
可是這么強大的緩存系統(tǒng),其實也存在很多問題呢,那便是緩存雪崩、緩存擊穿、緩存穿透。不過也不要害怕,有問題就有解法,我們慢慢的往下看。
所謂緩存雪崩,指的是緩存數(shù)據(jù)同一時間大量失效,所有的請求全打到數(shù)據(jù)庫,導致數(shù)據(jù)庫在巨大壓力下掛掉。比如在雙十一的時候,用戶都會打開淘寶買東西,有的人是真的有需要買的,有的人就是湊個熱鬧,不管怎么樣,這時候首頁的壓力就非常大了,為了滿足所有用戶都可以訪問到數(shù)據(jù),阿里的程序員們將首頁數(shù)據(jù)緩存到redis里,并設置redis失效時間是12小時。我們知道redis是內存數(shù)據(jù)庫,那訪問速度,杠杠的啊。數(shù)據(jù)緩存后用戶們買的很開心,程序員們也很開心,系統(tǒng)都還好著呢…..慢慢的12個小時過去了,用戶購物的熱情不減啊,還是大量的用戶請求在過來,然而首頁redis緩存的數(shù)據(jù)全失效了,這時候redis里沒有數(shù)據(jù)了,用戶請求直接撲向數(shù)據(jù)庫,數(shù)據(jù)庫哪能扛的住啊,直接垮掉。
應對緩存雪崩,我們也有一些辦法,比如隨機設置key的失效時間,避免大量的key同時失效,比如不要設置過期時間或把過期時間設置的很長,再比如運行定時任務,隨時監(jiān)控緩存情況,在失效前刷新進新的緩存。
所謂緩存穿透,指的是緩存中沒有緩存到該數(shù)據(jù),從而導致請求直接到達數(shù)據(jù)庫,數(shù)據(jù)庫在巨大壓力下掛掉。比如在雙十一的時候,有黑客經過多次攻擊測試發(fā)現(xiàn)混沌炸雞(假設商品ID為-1)這個商品在網站上沒有,于是便寫了一個腳本,大量的去請求這個商品,redis緩存一看我只有炸雞商品,不滿足需求啊,于是就放到數(shù)據(jù)庫那里了,所有的請求全放給數(shù)據(jù)庫了,數(shù)據(jù)庫說我也沒有啊,但還是不斷的被接受輪詢,結果直接垮掉。
應對緩存穿透,我們也有一些辦法,比如對于某些不存在的數(shù)據(jù)緩存在redis時設置為null,比如對請求參數(shù)進行校驗,不合法的直接攔截,比如增加安全防護,定期掃描,有發(fā)現(xiàn)不正常的數(shù)據(jù)直接將該請求的IP地址加入黑名單。
所謂緩存擊穿,指的是緩存的熱點數(shù)據(jù)突然失效導致大量的請求都去訪問數(shù)據(jù)庫,數(shù)據(jù)庫扛不住壓力,直接掛掉。比如雙十一的時候,iPhone12在凌晨00:00-01:00可1分錢搶購,哇,這個可是真便宜呢,程序員們也預測到了商品的火爆,于是將iPhone12的商品信息緩存到redis中,設置了1小時過期。iPhone12是新推出的商品,引起了一億人的關注,男女老少全都蜂擁而至,只為了搶購一個iPhone,到了59分的時候,突然iPhone12在redis的數(shù)據(jù)過期了,這時候大量的請求都到了數(shù)據(jù)庫,數(shù)據(jù)庫直接垮掉了。
應對緩存擊穿,我們也有一些辦法,比如設置熱點數(shù)據(jù)永不過期,比如給數(shù)據(jù)加鎖,當有線程請求不到數(shù)據(jù)時,其它的用戶線程也無法請求數(shù)據(jù),直到第一個線程拿到數(shù)據(jù)后,去redis緩存起來,其它的線程仍然走緩存拿數(shù)據(jù),比如服務降級,直接返回“商品太火爆了,系統(tǒng)暫時休息會兒”。
通過本文的介紹,相信你對緩存、緩存雪崩、緩存擊穿、緩存穿透也有了對應的了解了吧。當你所在的業(yè)務因為高并發(fā)、大數(shù)據(jù)量準備啟用緩存策略時,對于緩存可能帶來的雪崩、擊穿、穿透問題要做好防護措施,這樣大家都可以開開心心的玩耍了!