緩存穿透與雪崩及支付寶2018年面試題剖析

一、什麼是緩存?

  ☞ 緩存就是數據交換的緩衝區(稱作:Cache),當某一硬件要讀取數據時,會首先從緩存彙總查詢數據,有則直接執行,不存在時從內存中獲取。由於緩存的數據比內存快的多,所以緩存的作用就是幫助硬件更快的運行。
  ☞ 緩存往往使用的是RAM(斷電既掉的非永久存儲),所以在用完後還是會把文件送到硬盤等存儲器中永久存儲。電腦中最大緩存就是內存條,硬盤上也有16M或者32M的緩存。
  ☞ 高速緩存是用來協調CPU與主存之間存取速度的差異而設置的。一般CPU工作速度高,但內存的工作速度相對較低,爲了解決這個問題,通常使用高速緩存,高速緩存的存取速度介於CPU與主存之間。系統將一些CPU在最近幾個時間段經常訪問的內容存在高速緩存,這樣就在一定程度上緩解了由於主存速度低造成的CPU“停工待料”的情況。
  ☞ 緩存就是把一些外存上的數據保存在內存上而已,爲什麼保存在內存上,我們運行的所有程序裏面的變量都是存放在內存中的,所以如果想將值放入內存上,可以通過變量的方式存儲。在JAVA中一些緩存一般都是通過Map集合來實現的。

▁▂▃▅▆ :緩存在不同的場景下,作用是不一樣的具體舉例說明:
✔ 操作系統磁盤緩存 ——> 減少磁盤機械操作。
✔ 數據庫緩存——>減少文件系統IO。
✔ 應用程序緩存——>減少對數據庫的查詢。
✔ Web服務器緩存——>減少應用服務器請求。
✔ 客戶端瀏覽器緩存——>減少對網站的訪問。

二、緩存穿透

什麼是緩存穿透?發生的原因?

1、緩存穿透: 緩存穿透是指用戶查詢數據,在數據庫沒有,自然在緩存中也不會有。這樣就導致用戶查詢的時候, 在緩存中找不到對應key的value,每次都要去數據庫再查詢一遍,然後返回空(相當於進行了兩次
無用的查詢)。這樣請求就繞過緩存直接查數據庫
誘發原因:惡意攻擊

2、有什麼解決方案來防止緩存穿透?

  1. 緩存空值如果一個查詢返回的數據爲空(不管是數據不 存在,還是系統故障)我們仍然把這個空結果進行緩存,但它的過期時間會很短,最長不超過五分鐘。通過這個直接設置的默認值存放到緩存,這樣第二次到緩衝中獲取就有值了,而不會繼續訪問數據庫

  2. 採用布隆過濾器BloomFilter 優勢佔用內存空間很小,bit存儲。性能特別高。 將所有可能存在的數據哈希到一個足夠大的 bitmap 中,一個一定不存在的數據會被這個bitmap 攔截掉,從而避免了對底層存儲系統的查詢壓力

三、緩存擊穿

什麼是緩存擊穿?發生原因?

上面提到的某個數據沒有,然後好多請求查詢數據庫,可以歸爲緩存擊穿的範疇:對於熱點數據,當緩存失效的一瞬間,所有的請求都被下放到數據庫去請求更新緩存,數據庫被壓垮。

解決方案:

  1. 一種思路是加全局鎖,就是所有訪問某個數據的請求都共享一個鎖,獲得鎖的那個纔有資格去訪問數據庫,其他線程必須等待。
  2. 對即將過期的數據進行主動刷新,比如新起一個線程輪詢數據,或者比如把所有的數據劃分爲不同的緩存區間,定期分區間刷新數據。該思路也是緩存雪崩的解決方案之一

四、緩存雪崩

什麼是緩存雪崩?發生原因?

緩存雪崩是指當我們給所有的緩存設置了同樣的過期時間,當某一時刻,整個緩存的數據全部過期了,然後瞬間所有的請求都被拋向了數據庫,數據庫就崩掉了。——實際上就是連鎖式緩存穿透 導致性能急速下降

解決方案:

  1. 加鎖排隊 key: whiltList value:1000w個uid 指定setNx whiltList valuenullValuemutex互斥鎖解決,Redis的SETNX去set一個mutex key,當操作返回成功時,再進行load db的操作並回設緩存;否則,就重試整個get緩存的方法
  2. 數據預熱 在系統上線後將相關數據加載到緩存系統,避免用戶訪問之間訪問數據庫而不是緩存
  3. 雙層緩存策略 其實就是爲你的緩存"買一個保險" 做個備份 當A緩存失效後 直接訪問B緩存 注:A緩存失效的時間短 B(備份緩存)失效時間長
  4. 定時更新緩存

關於加鎖 setnx 與setex 操作 :一般來說,setnx&setex 可以應對分佈式鎖的大部分需求場景 但是這樣卻會產生一個問題!!——那就是無法實現可重入鎖 也就是說只能鎖無法解鎖

加鎖流程
在這裏插入圖片描述
會產生問題
在這裏插入圖片描述

1、當qps 流量請求過多 導致項目服務宕機 導致Redis鎖無法釋放 其他機器無法獲取鎖
2、當緩存雪崩導致Redis宕機 獲取不到鎖
3、當setnx 和setex之間發生服務宕機 導致Redis鎖永遠不會過期

解決方案:

  1. 手動刪除key
  2. 使用lua腳本 把setnx 和setex兩個指令放到一起

五、緩存刷新

什麼是緩存刷新?

既清空緩存 ,一般在insert、update、delete操作後就需要刷新緩存,如果不執行就會出現髒數據。但當緩存請求的系統蹦掉後,返回給緩存的值爲null。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章