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