1.緩存穿透
是指當用戶在查詢一條數(shù)據(jù)的時候丈牢,而此時數(shù)據(jù)庫和緩存都沒有關(guān)于這條數(shù)據(jù)的任何記錄车柠,而這條數(shù)據(jù)在緩存中沒找到就會向數(shù)據(jù)庫請求獲取數(shù)據(jù)跌宛。它拿不到數(shù)據(jù)時相种,是會一直查詢數(shù)據(jù)庫威恼,這樣會對數(shù)據(jù)庫的訪問造成很大的壓力。至于如何解決緩存穿透的問題寝并,一般有兩種:
緩存空對象箫措。
緩存空對象它就是指一個請求發(fā)送過來,如果此時緩存中和數(shù)據(jù)庫都不存在這個請求所要查詢的相關(guān)信息衬潦,那么數(shù)據(jù)庫就會返回一個空對象斤蔓,并將這個空對象和請求關(guān)聯(lián)起來存到緩存中,當下次還是這個請求過來的時候镀岛,這時緩存就會命中弦牡,就直接從緩存中返回這個空對象,這樣可以減少訪問數(shù)據(jù)庫的壓力漂羊,提高當前數(shù)據(jù)庫的訪問性能驾锰。如下面這個流程。
但是使用緩存空對象會導(dǎo)致的一個問題:如果時間一長這樣會導(dǎo)致緩存中存在大量空對象走越,這樣不僅會占用許多的內(nèi)存空間椭豫,還會浪費許多資源≈贾福可以在設(shè)置空對象的時間赏酥,順便設(shè)置一個過期時間,就可以解決個問題谆构。
布隆過濾器裸扶。
布隆過濾器能準確過濾掉那些已經(jīng)看過的內(nèi)容,那些沒有看過的新內(nèi)容低淡,它也會過濾掉極小一部分 (誤判)姓言,但是絕大多數(shù)新內(nèi)容它都能準確識別。這樣就可以完全保證推薦給用戶的內(nèi)容都是無重復(fù)的蔗蹋。通俗的講就是當布隆過濾器說某個值存在時何荚,這個值可能不存在;當它說不存在時猪杭,那就肯定不存在餐塘。
2.緩存擊穿。
緩存擊穿是指有某個key經(jīng)常被查詢皂吮,經(jīng)常被用戶特殊關(guān)懷戒傻,用戶非常 love 它 (▽)税手,也就類比“熟客” 或者 一個key經(jīng)常不被訪問。但是這時候需纳,如果這個key在緩存的過期時間失效的時候或者這是個冷門key時芦倒,這時候突然有大量有關(guān)這個key的訪問請求,這樣會導(dǎo)致大并發(fā)請求直接穿透緩存不翩,請求數(shù)據(jù)庫兵扬,瞬間對數(shù)據(jù)庫的訪問壓力增大。即緩存沒有口蝠,數(shù)據(jù)庫有器钟。
歸納起來:造成緩存擊穿的原因有兩個。
(1)一個“冷門”key妙蔗,突然被大量用戶請求訪問傲霸。
(2)一個“熱門”key,在緩存中時間恰好過期眉反,這時有大量用戶來進行訪問.
對于緩存擊穿的問題:我們常用的解決方案是加鎖昙啄。對于key過期的時候,當key要查詢數(shù)據(jù)庫的時候加上一把鎖寸五,這時只能讓第一個請求進行查詢數(shù)據(jù)庫跟衅,然后把從數(shù)據(jù)庫中查詢到的值存儲到緩存中,對于剩下的相同的key播歼,可以直接從緩存中獲取即可伶跷。在分布式環(huán)境下我們可以使用分布式鎖,如:基于數(shù)據(jù)庫秘狞、基于Redis的分布式鎖叭莫。
緩存雪崩
緩存雪崩是指在某一個時間段內(nèi),緩存集中過期失效烁试,如果這個時間段內(nèi)有大量請求雇初,而查詢數(shù)據(jù)量巨大,所有的請求都會達到存儲層减响,存儲層的調(diào)用量會暴增靖诗,引起數(shù)據(jù)庫壓力過大甚至宕機。
對于緩存雪崩有以下解決方案:
(1)redis高可用
Redis有可能掛掉支示,多增加幾臺redis實例刊橘,(一主多從或者多主多從),這樣一臺掛掉之后其他的還可以繼續(xù)工作颂鸿,其實就是搭建的集群促绵。
(2)限流降級
在緩存失效后,通過加鎖或者隊列來控制讀數(shù)據(jù)庫寫緩存的線程數(shù)量,對某個key只允許一個線程查詢數(shù)據(jù)和寫緩存败晴,其他線程等待浓冒。
(3)數(shù)據(jù)預(yù)熱
數(shù)據(jù)加熱的含義就是在正式部署之前,我先把可能的數(shù)據(jù)先預(yù)先訪問一遍尖坤,這樣部分可能大量訪問的數(shù)據(jù)就會加載到緩存中稳懒。在即將發(fā)生大并發(fā)訪問前手動觸發(fā)加載緩存不同的key。
(4)不同的過期時間
設(shè)置不同的過期時間慢味,讓緩存失效的時間點盡量均勻僚祷。