老徐和阿珍的故事:緩存穿透、緩存擊穿、緩存雪崩、緩存熱點,傻傻分不清楚


人物背景

老徐,男,本名徐福貴,從事Java相關研發工作多年,職場老油條,摸魚小能手,雖然歲數不大但長的比較着急,人稱老徐。據說之前炒某幣敗光了所有家產,甚至現在還有欠債。

阿珍,女,本名陳家珍,剛剛入職不久的實習生,雖然是職場菜鳥但聰明好學。據說是學校的四大校花之一,追求她的人從旺角排到了銅鑼灣,不過至今還單身。

微信掃描二維碼關注后回復「電子書」,獲取12本Java必讀技術書籍。

阿珍:“在高並發下遇到瓶頸的時候,經常會用到緩存來提高整個系統的性能。”

老徐:“嗯,不過緩存能夠大大提升整個系統的性能,但同時也引入了更多復雜性。”

阿珍點了點頭,說:“是啊,緩存穿透、緩存擊穿、緩存雪崩、緩存熱點這些東西,這些東西我一直分不清楚,經常混淆。”

老徐立刻自信滿滿地說:“這個我懂啊,你聽我給你娓娓道來。”

緩存穿透

緩存穿透是指在查詢緩存數據時,緩存和數據庫中都沒有對應數據,在緩存中找不到對應的數據,每次都要去數據庫中再查詢一遍,然后返回數據不存在。

在這個場景中,緩存並沒有起到分擔數據庫訪問壓力的作用。讀取不存在的數據的請求量一般不會太大,但如果出現一些惡意攻擊,故意大量訪問某些不存在的數據,就會對數據庫造成很多壓力。

阿珍:“太可怕了,萬一遇到了這樣攻擊,該怎么辦呀?”

老徐:“這個很好應對的,一般有兩種辦法。”

第一個是:如果查詢數據庫中的數據沒有找到,則直接設置一個特定值存到緩存中。之后讀取緩存時就會獲取到這個特定值,直接返回空值,就不會繼續訪問數據庫了。

第二個是:把已存在數據的key存放在布隆過濾器中。當有新的請求時,先到布隆過濾器中查詢是否存在,如果不存在該條數據直接返回;如果存在該條數據再查詢緩存查詢數據庫。

微信掃描二維碼關注后回復「電子書」,獲取12本Java必讀技術書籍。

緩存擊穿

緩存擊穿是指在查詢緩存數據時,數據庫原本有得數據,但是緩存中沒有,生成緩存數據需要耗費較長時間或者大量資源,這時候如果有大量請求該數據,會對數據庫甚至系統造成較大壓力。

阿珍:“哦?該怎么解決呀?”

老徐:“這個很好解決,一般有兩個做法。”

第一個是:對緩存更新操作加入鎖的保護,保證只有一個線程能夠進行緩存更新的操作,沒有獲取更新鎖的線程要么等待鎖釋放后重新讀取緩存,要么直接返回空值或者默認值。

第二個是:后台作業定時更新緩存,而不是在訪問頁面時生成緩存數據。這樣可以按照一定策略定時更新緩存,不會對存儲系統較大的瞬時壓力。

微信掃描二維碼關注后回復「電子書」,獲取12本Java必讀技術書籍。

緩存雪崩

緩存雪崩是指當大量緩存同時失效或過期后,大量請求直接訪問對數據庫,甚至耗費較長時間或者大量資源計算緩存結果,引起系統性能的急劇下降。

阿珍搶先說道:“這個我知道怎么解決!”老徐反問:“怎么解決?”

阿珍回答:“同一類型的緩存的過期時間可以設置一個隨機值,比如:原來的過期時間是5分鍾,在此基礎上加060秒,那么過期時間就變為在56分鍾內波動,有效防止都在同一個時間點上大量緩存過期。”

緩存熱點

緩存熱點是指大部分甚至所有的業務請求都命中同一份緩存數據。

雖然緩存本身的性能比較高,但對於一些特別熱點的數據,如果大部分甚至所有的請求都命中同一份緩存數據,則這份數據所在的緩存服務器的壓力也會很大。比如,電商的爆品秒殺活動,短時間內被上千萬的用戶訪問。

阿珍:“遇到了這種情況,該怎么辦呀?”

老徐:“這個很好解決的,一般有兩種辦法:復制多份緩存副本和本地內存緩存。”

復制多份緩存副本,就是將請求分散到多個緩存服務器上,減輕緩存熱點導致的單台緩存服務器壓力。在設計緩存副本的時候,有一個細節需要注意:不同的緩存副本不要設置統一的過期時間,否則就會出現所有緩存副本同時生成同時失效的情況,從而引發緩存的雪崩效應。

微信掃描二維碼關注后回復「電子書」,獲取12本Java必讀技術書籍。

把熱點數據緩存在客戶端的本地內存中,並且設置一個失效時間。對於每次讀請求,將首先檢查該數據是否存在於本地緩存中,如果存在則直接返回,如果不存在再去訪問分布式緩存的服務器。

阿珍用崇拜的眼神看着老徐,說:“老徐,你太牛了,什么都懂!”

老徐不好意思地撓了撓頭,說:“也沒有了。”

微信掃描二維碼關注后回復「電子書」,獲取12本Java必讀技術書籍。

最后,謝謝你這么帥,還給我點贊關注


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM