業內人士都聽說過緩存擊穿與緩存雪崩。緩存擊穿它是指某一key經常被用戶特別關注經常被查詢,而恰好此時間節點對Key有大量的并發請求過來,龐大數量的請求打到db,這些請求有坑你會直接擊穿高速緩存,數據庫的訪問壓力也會瞬間被擊穿。緩存雪崩它是指緩存中的大量數據到了過期時間,這種巨大的數據導致了數據庫壓力過大,甚至down機。下面我們就來詳細介紹一下緩存擊穿和緩存雪崩。
一般來說,緩存穿透的場景發生在故意攻擊的場景下;比如說,本來查詢意見商品的序號是正數,但是請求方總是請求大量的負數過來,導致緩存無效,全部流量都打在了數據庫中,如果某一時刻流量過大,則會導致數據庫崩潰;緩存雪崩是指緩存中數據大批量到過期時間,而查詢數據量巨大,引起數據庫壓力過大甚至down機。緩存擊穿是指熱點key在某個時間點過期的時候,而恰好在這個時間點對這個Key有大量的并發請求過來,從而大量的請求打到db。
一、緩存擊穿:如果數據庫中有緩存,CPU中有緩存,那么模擬真實數據的原因就更多了。我們應該避免在不需要緩存的情況下緩存和合理的模擬。在項目的實際開發和部署過程中,為了減輕db的壓力,必須使用Nosql作為中間介質,以減少數據庫的I/O操作,從而提高系統訪問效率。作為最常用的緩存處理工具,Redis在使用過程中必須對緩存穿透、緩存擊穿和緩存雪崩有詳細的了解。高速緩存破壞是指key經常被查詢,用戶經常關注。正如熟客或key經常不訪問一樣,用戶非常喜歡它。但是在這個時候,如果key在高速緩存到期時失效或者是冷門key,那么在這個時候突然出現了大量的訪問請求,這就會導致大并發請求直接穿透高速緩存,請求數據庫,瞬間增加訪問數據庫的壓力。
歸納起來:緩存破壞有兩個原因。
1、一個冷門key突然被大量用戶要求訪問。
2、一款熱門key,緩存時間正好過期,此時有大量的用戶訪問。
我們的業務通常會經常訪問幾個數據,比如秒殺活動,這些頻繁訪問的數據被稱為熱點數據。如果緩存中的熱點數據過期,此時需要大量訪問熱點數據,則無法從緩存中讀取。如果直接訪問數據庫,數據庫很容易被高并發性要求沖走,這就是緩存損壞的問題。有關緩存擊穿的問題:我們常用的解決辦法是加鎖。在key過期時,在key想要查詢數據庫時添加一把鎖,此時只能讓第一個請求查詢數據庫,然后將從數據庫中查詢到的值存儲在其他相同的key中,這樣就可以直接從緩存中獲得。
二、緩存雪崩:緩存雪崩是指當數據緩存到期時,大量的查詢數據會導致數據庫壓力過大,甚至down機。不像緩存擊穿,緩存擊穿是指同一數據的并發查詢,緩存雪崩是不同數據的過期時間,很多數據無法查詢,從而查詢數據庫。
理由:
Redis突然停止了。
大部分數據無效。
舉例來說,我們基本上都經歷過購物狂歡,假辦了23:00-24:00的商品骨折促銷活動。程序小哥哥在23:00將商家骨折的商品放入緩存中,并通過redis的expire設置了一個小時的過期時間。在此期間,許多用戶會訪問這些商品信息、購買等。但正好在24:00時,碰巧有許多用戶正在訪問這些商品,此時訪問這些商品就會落到數據庫上,造成數據庫承受著巨大的壓力,稍有不慎就會直接導致數據庫。
緩存雪崩有以下解決方案:
1、redis高度可用。
redis有可能掛掉,增加一些redis實例(一主多從或多主多從),這樣一個掛掉之后其他的就可以繼續工作了,實際上就是建立了一個集群。
2、限制流量降級。
緩存失效后,通過鎖定或隊列控制讀取數據庫中緩存的線程。在某些密鑰中,只有一個線程可以查詢數據和寫入緩存,其他線程可以等待。
3、數據預熱。
資料加熱是指在正式部署之前,我會提前訪問可能的數據,這樣可能會將大量訪問的數據加載到緩存中。在進行大并發訪問之前,手動觸發加載緩存。
4、不同的過期時間。
設定不同的過期時間,使緩存故障時間盡可能均勻。
以上我們分享了緩存擊穿和緩存雪崩的詳細介紹了。一般來講我們設計一個緩存系統,必須考慮的問題就是緩存穿透,緩存擊穿以及失效時的雪崩效應,如果您對相關知識感興趣,可以繼續關注中培偉業。