這篇文章主要講解了“怎么解決redis緩存雪崩、擊穿與穿透問題”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么解決Redis緩存雪崩、擊穿與穿透問題”吧!
目前創新互聯已為1000+的企業提供了網站建設、域名、雅安服務器托管、網站托管、服務器托管、企業網站設計、永靖網站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協力一起成長,共同發展。
緩存雪崩是指大量的請求無法命中Redis中的緩存數據,也就是在Redis找不到數據了,那業務系統只能到數據庫中查詢,進而導致所有的請求都發送到了數據庫。如下圖所示:

數據庫并不像Redis能處理大量請求,由緩存雪崩導致的請求激增必須會導致數據庫所在宕機,這樣勢必會影響業務系統,所以如果發生緩存雪崩,對于業務系統肯定是致命的。
什么情況下出現緩存雪崩呢?總結起來有以下兩個方面的原因:
大量Redis緩存數據同時過期,導致所有的發送到Redis請求都無法命中數據,只能到數據庫中進行查詢。
Redis服務器宕機,所有請求都無法經Redis來處理,只能轉向數據庫查詢數據。
針對導致緩存雪崩的原因,有不同的解決方法:
針對大量緩存隨機過期時間,解決方法就是在原始過期時間的基礎上,再加一個隨機過期時間,比如1到5分鐘之間的隨機過期時間,這樣可以避免大量的緩存數據在同一時間過期。
而針對Redis解決宕機的導致的緩存雪崩,可以提前搭建好Redis的主從服務器進行數據同步,并配置哨兵機制,這樣在Redis服務器因為宕機而無法提供服務時,可以由哨兵將Redis從服務器設置為主服務器,繼續提供服務。
緩存擊穿與緩存雪崩的情況相似,雪崩是因為大量的數據過期,而緩存擊穿則是指熱點數據過期,所有針對熱點數據的請求都需要到數據庫中進行處理,如下圖所示:

解決緩存擊穿的三種方式:
不設置過期時間
如果我們能提前知道某個數據是熱點數據,那么就可以不設置這些數據的過期,從而避免緩存擊穿問題,比如一些秒殺活動的商品,在秒殺時會大量用戶訪問,這時候我們就可以將這些用于秒殺的商品數據提前寫入緩存并且不設置過期時間。
互斥鎖
提前知道某些數據會有大量訪問,我們當然可以設置不過期,但更多時候,我們并不能提前預知,這種情況要怎么處理呢?
我們來分析一下緩存擊穿的情況:
正常情況下,當某個Redis緩存數據過期時,如果有對該數據的請求,則重新到數據庫中查詢并再寫入緩存,讓后續的請求可以命中該緩存而無須再去數據庫中查詢。
而熱點數據過期時,由于大量請求,當某個請求無法命中緩存時,會去查詢數據庫并重新把數據寫入Redis,也就是在寫入Redis之前,其他請求進來,也會去查詢數據庫。
好了,我們知道熱點數據過期后,很多請求會去查詢數據庫,那么我們可以給去查詢數據庫的業務邏輯加個互斥鎖,只有獲得鎖的請求才能去查詢數據庫并把數據寫回Redis,而其他沒有獲得鎖的請求只能等待數據就緒。
上述步驟的如下圖所示:

設置邏輯過期時間
使用互斥鎖雖然可以非常簡單地解決緩存擊穿問題,但沒有獲得鎖的請求雖然排隊等待,這樣影響了系統的性能,還有另一種解決緩存擊穿的方法就是在業務數據冗余一個過期時間,比如下面的數據中我們增加了expire_at字段用于表示數據過期時間。
{"name":"test","expire_at":"1599999999"}復制代碼
這種方式的實現過程如下圖所示:

緩存中的熱點數據中冗余一個邏輯過期時間,但數據在Redis不設置過期時間
當一個請求拿到Redis中的數據時,判斷邏輯過期時間是否到期,如果沒有到期,直接返回,如果到期則開啟另一個線程獲得鎖后去查詢數據庫并將查詢的最新數據寫回Redis,而當前請求返回已經查詢的數據。
緩存穿透是指要查找的數據既不在緩存當中,也不在數據庫中,因為不在緩存中,所以請求一定會到達數據庫,Redis緩存形同虛設,如下圖所示:

什么條件下會發生緩存穿透呢?主要有以下三種情況:
用戶惡意攻擊請求
誤操作把Redis和數據庫里的數據刪除了
用戶還未產生內容時,比如用戶的文章列表,用戶還未寫文章,所以緩存和數據庫都沒有數據
當在Redis緩存中查詢不到數據時,再從數據庫查詢,如果同樣沒有數據,就直接緩存一個空間或缺省值,這樣可以避免下次再去查詢數據庫;不過為了防止之后已經數據庫已經相應數據庫,再返回空值問題,應該為緩存設置過期時間,或者在產生數據時直接清除對應的緩存空值。
雖然緩存空值可以解決緩存穿透問題,但仍然需要查詢一次數據庫才能確定是否有數據,如果有用戶惡意攻擊,高并發地使用系統不存在的數據id進行查詢,所有的查詢都要經過數據庫,這樣仍然會給數據庫帶來很大的壓力。
所以,有沒有不用查詢數據庫就能確定數據是否存在的辦法呢?有的,用布隆過濾器。
布隆過濾器主要是兩個部分:bit數組+N個哈希函數,其原理為:
使用N個哈希函數對所要標記的數據進行哈希值計算。
將計算到的哈希值對bit數組的長度取模,這樣可以得到每個哈希值在bit數組的位置。
把bit數組中對應的位置標記為1。
下面是布隆過濾器原理示意圖:

當要進行數據寫入時,執行述述步驟,計算對應bit數組位置并標識為1,那么在執行查詢時,就能查詢該數據是否存在了。
另外,由于哈希碰撞問題導致的誤差,所以不存在的數據經過布隆過濾器后,會被判定為存在,再去查數據庫,不過哈希碰到的概率很小,用布隆過濾器已經能幫我們攔截大部分的穿透請求了。
Redis本身就支持布隆過濾器,所以我們可以直接使用Redis布隆過濾器,而不用自己去實現,非常方便。
緩存的雪崩、擊穿、穿透是在業務應用緩存時經常會碰到的緩存異常問題,其原因與解決方法如以下表示所示:
| 問題 | 原因 | 解決方法 |
|---|---|---|
| 緩存雪崩 | 大量數據過期或Redis服務器宕機 | 1. 隨機過期時間 2. 主從+哨兵的集群 |
| 緩存擊穿 | 熱點數據過期 | 1. 不設置過期時間 2. 加互斥鎖 3. 冗余邏輯過期時間 |
| 緩存穿透 | 請求數據庫和Redis都沒有的數據 | 1. 緩存空值或缺省值 2. 布隆過濾器 |
感謝各位的閱讀,以上就是“怎么解決Redis緩存雪崩、擊穿與穿透問題”的內容了,經過本文的學習后,相信大家對怎么解決Redis緩存雪崩、擊穿與穿透問題這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創新互聯,小編將為大家推送更多相關知識點的文章,歡迎關注!
分享名稱:怎么解決Redis緩存雪崩、擊穿與穿透問題
瀏覽地址:http://www.js-pz168.com/article32/jgijpc.html
成都網站建設公司_創新互聯,為您提供、網站內鏈、全網營銷推廣、微信公眾號、企業建站、用戶體驗
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯