這篇文章給大家分享的是有關(guān)redis緩存問題的示例分析的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
成都創(chuàng)新互聯(lián)公司是一家網(wǎng)站設(shè)計公司,集創(chuàng)意、互聯(lián)網(wǎng)應(yīng)用、軟件技術(shù)為一體的創(chuàng)意網(wǎng)站建設(shè)服務(wù)商,主營產(chǎn)品:成都響應(yīng)式網(wǎng)站建設(shè)公司、品牌網(wǎng)站制作、網(wǎng)絡(luò)營銷推廣。我們專注企業(yè)品牌在網(wǎng)站中的整體樹立,網(wǎng)絡(luò)互動的體驗,以及在手機等移動端的優(yōu)質(zhì)呈現(xiàn)。網(wǎng)站制作、網(wǎng)站設(shè)計、移動互聯(lián)產(chǎn)品、網(wǎng)絡(luò)運營、VI設(shè)計、云產(chǎn)品.運維為核心業(yè)務(wù)。為用戶提供一站式解決方案,我們深知市場的競爭激烈,認真對待每位客戶,為客戶提供賞析悅目的作品,網(wǎng)站的價值服務(wù)。
在我們的實際業(yè)務(wù)場景中,Redis 一般和其他數(shù)據(jù)庫搭配使用,用來減輕后端數(shù)據(jù)庫的壓力,比如和關(guān)系型數(shù)據(jù)庫 MySQL 配合使用。
Redis 會把 MySQL 中經(jīng)常被查詢的數(shù)據(jù)緩存起來,比如熱點數(shù)據(jù),這樣當用戶來訪問的時候,就不需要到 MySQL 中去查詢了,而是直接獲取 Redis 中的緩存數(shù)據(jù),從而降低了后端數(shù)據(jù)庫的讀取壓力。
如果說用戶查詢的數(shù)據(jù) Redis 沒有,此時用戶的查詢請求就會轉(zhuǎn)到 MySQL 數(shù)據(jù)庫,當 MySQL 將數(shù)據(jù)返回給客戶端時,同時會將數(shù)據(jù)緩存到 Redis 中,這樣用戶再次讀取時,就可以直接從 Redis 中獲取數(shù)據(jù)。流程圖如下所示:
當然,我們在使用Redis作為緩存數(shù)據(jù)庫的過程中也并不是總能一帆風順,我們會遇到常見的三種緩存問題:
緩存穿透
緩存擊穿
緩存雪崩
緩存穿透是指當用戶查詢某個數(shù)據(jù)時,Redis 中不存在該數(shù)據(jù),也就是緩存沒有命中,此時查詢請求就會轉(zhuǎn)向持久層數(shù)據(jù)庫 MySQL,結(jié)果發(fā)現(xiàn) MySQL 中也不存在該數(shù)據(jù),MySQL 只能返回一個空對象,代表此次查詢失敗。如果這種類請求非常多,或者用戶利用這種請求進行惡意攻擊,就會給 MySQL 數(shù)據(jù)庫造成很大壓力,甚至于崩潰,這種現(xiàn)象就叫緩存穿透。
當 MySQL 返回空對象時, Redis 將該對象緩存起來,同時為其設(shè)置一個過期時間。當用戶再次發(fā)起相同請求時,就會從緩存中拿到一個空對象,用戶的請求被阻斷在了緩存層,從而保護了后端數(shù)據(jù)庫,但是這種做法也存在一些問題,雖然請求進不了 MSQL,但是這種策略會占用 Redis 的緩存空間。
首先將用戶可能會訪問的熱點數(shù)據(jù)的所有key存儲在布隆過濾器中(也稱緩存預(yù)熱),當有一個用戶請求時會先經(jīng)過布隆過濾器,布隆過濾器會判斷請求的key是否存在,若不存在,那么該請求將直接被拒絕,否則將繼續(xù)執(zhí)行查詢,先前往緩存中查詢,緩存沒有的話再前往數(shù)據(jù)庫中查詢。相較于第一種方法,用布隆過濾器方法更為高效、實用。其流程示意圖如下:
緩存預(yù)熱:是指系統(tǒng)啟動時,提前將相關(guān)的數(shù)據(jù)加載到 Redis 緩存系統(tǒng)中。這樣避免了用戶請求的時再去加載數(shù)據(jù)。
兩種方案都可以解決緩存穿透的問題,但其使用的場景卻不同:
緩存空對象:適用于空數(shù)據(jù)的key數(shù)量有限、key重復(fù)請求概率較高的場景。
布隆過濾器:適用于空數(shù)據(jù)的key各不相同、key重復(fù)請求概率較低的場景。
緩存擊穿是指用戶查詢的數(shù)據(jù)緩存中不存在,但是后端數(shù)據(jù)庫卻存在,這種現(xiàn)象出現(xiàn)原因是一般是由緩存中 key 過期導(dǎo)致的。比如一個熱點數(shù)據(jù) key,它無時無刻都在接受大量的并發(fā)訪問,如果某一時刻這個 key 突然失效了,就致使大量的并發(fā)請求進入后端數(shù)據(jù)庫,導(dǎo)致其壓力瞬間增大。這種現(xiàn)象被稱為緩存擊穿。
設(shè)置熱點數(shù)據(jù)永不過期。
采用分布式鎖的方法,重新設(shè)計緩存的使用方式,過程如下:
上鎖:當我們通過 key 去查詢數(shù)據(jù)時,首先查詢緩存,如果沒有,就通過分布式鎖進行加鎖,第一個獲取鎖的進程進入后端數(shù)據(jù)庫查詢,并將查詢結(jié)果緩到Redis 中。
解鎖:當其他進程發(fā)現(xiàn)鎖被某個進程占用時,就進入等待狀態(tài),直至解鎖后,其余進程再依次訪問被緩存的 key。
永遠不過期 :這種方案由于沒有設(shè)置真正的過期時間,實際上已經(jīng)不存在熱點 key 產(chǎn)生的一系列危害,但是會存在數(shù)據(jù)不一致的情況,同時代碼復(fù)雜度會增大。
互斥鎖:這種方案思路比較簡單,但是存在一定的隱患,如果構(gòu)建緩存過程出現(xiàn)問題或者時間較長,可能會存在死鎖和線程池阻塞的風險,但是這種方法能夠較好的降低后端存儲負載并在一致性上做的比較好。
緩存雪崩是指緩存中大批量的 key 同時過期,而此時數(shù)據(jù)訪問量又非常大,從而導(dǎo)致后端數(shù)據(jù)庫壓力突然暴增,甚至會掛掉,這種現(xiàn)象被稱為緩存雪崩。它和緩存擊穿不同,緩存擊穿是在并發(fā)量特別大時,某一個熱點 key 突然過期,而緩存雪崩則是大量的 key 同時過期,因此它們根本不是一個量級。
緩存雪崩和緩存擊穿有相似之處,所以也可以采用熱點數(shù)據(jù)永不過期的方法,來減少大批量的 key 同時過期。再者就是為 key 設(shè)置隨機過期時間,避免 key 集中過期。
一臺Redis可能會因為雪崩而掛掉,那么可以多增設(shè)幾臺Redis,搭建集群,如果一臺掛掉之后,其他的還可以繼續(xù)工作。
感謝各位的閱讀!關(guān)于“Redis緩存問題的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!