1. 程式人生 > 其它 >redis快取穿透和雪崩(重要工作面試)

redis快取穿透和雪崩(重要工作面試)

服務高可用問題

Redis快取的使用,極大的提升了應用程式的效能和效率,特別是資料查詢方面,同時也帶來了一些問題。其中,最要害的問題,

就是資料的一致性問題,嚴格意義上這個問題無解。對資料一致性要求很高,就不能使用快取

 

快取穿透:(查不到)

  使用者查一個數據,發現redis記憶體資料庫沒有,也就是快取沒有命中,於是向持久層資料庫查詢,發現也沒有,本次查詢失敗。

當用戶很多的時候,快取都沒有命中(秒殺場景),於是都請求了持久層資料,這會給持久層資料庫造成很大的壓力,相當於出現了快取穿透。

解決方案

  布隆過濾器:是一種資料結構,對所有可能查詢的引數以hash形式儲存,在控制層先進行校驗,不符合則丟棄,從而避免了對底層儲存系統的查詢壓力。

  

 

   快取空物件:

  當儲存層不命中後,即使返回的空物件也將其快取起來,同時會設定一個過期時間,之後再訪問這個資料庫將從快取中取出,

保護了後端資料來源。

  

 

 這種方法存在問題:

  1、如果控制能夠被快取起來,意味著快取需要更多的空間儲存更多的鍵,當中可能會有很多空值的鍵

  2、即使對空值設定了過期時間,還是會存在快取層和儲存層的資料會有一段時間的視窗不一致,這對於需要保持一致性的業務會有影響。

 

快取擊穿:(量太大,快取過期)

  微博伺服器宕機

  與快取穿透區別:快取擊穿是指一個key非常熱點,在不停扛著高併發,高併發集中對這一個點訪問,當這個key在失效的瞬間,持續的大併發就穿破快取,直接請求資料庫。

  當某個key在過期的瞬間,有大量的請求併發訪問,這類資料一般是熱點資料,由於快取過期,會同時訪問資料庫來查詢最新的資料,並且回寫快取,會導致資料庫瞬間壓力增大。

解決方法

  1、設定熱點資料永不過期

  從快取層面來看,沒有設定過期時間,所以不會出現熱點key過期後產生的問題

  2、加互斥鎖

  分散式鎖:使用分散式鎖,保證對於每個key同時只有一個執行緒去查詢後端服務,其他執行緒沒有獲得分散式鎖的許可權,因此只需要等待即可。這種方法將高併發的壓力轉移到了分散式鎖,因此對分散式鎖的考驗很大。

 

快取雪崩:

  在某一個時間段,快取集中過期失效,redis宕機

  產生雪崩的原因之一:比如在寫本文的時候,雙十二搶購,商品集中放在了快取,假設快取一小時,到了凌晨一點時候,這批商品快取過期。而對這批商品的訪問查詢,都落到了資料庫上,對於資料庫而言,產生週期性的壓力波峰。於是所有的請求都會達到儲存層,儲存層的呼叫量暴增,造成儲存層掛掉的情況。

  

 

 其實集中過期,倒不是非常致命,比較致命的快取雪崩,是快取伺服器某個節點宕機或者斷網。因為自然形成的快取雪崩,一定是在某個時間段集中建立快取,這個時候,資料庫也是可以頂住壓力的。無非就是對資料庫產生週期性的壓力,而快取服務節點宕機,對資料庫伺服器造成的壓力是不可預知,很有可能瞬間把資料庫擊穿

雙十一:一般停掉一些服務(當天退不了款等),(保證主要的服務可用!)

解決方案:

  redis高可用

  既然redis有可能掛掉,多增設幾臺redis,一臺掛掉其它幾臺也可以工作,就是搭建的叢集。(異地多活)

  限流降級(在springcloud)

  快取失效後,通過加鎖或者佇列來控制讀資料庫寫快取的執行緒數量。比如對某個key只允許一個執行緒查詢資料和寫快取,其它執行緒等待。

  資料預熱

  資料加熱的含義就是在正是部署之前,我先把可能的資料先預先訪問一遍,這樣部分大量訪問的資料就會載入到快取中,在即將發生大併發訪問前手動觸發載入快取不同的key,設定不同的過期時間,讓快取失效的時間點儘量均勻。