1. 程式人生 > 其它 >17.redis的快取穿透與雪崩(重要)

17.redis的快取穿透與雪崩(重要)

一、快取穿透 1、概念 快取穿透的概念很簡單,使用者想要查詢一個數據,發現redis記憶體資料庫沒有,也就是快取沒有命中,於是向持久層資料庫查詢。發現也沒有,於是本次查詢失敗。當用戶很多的時候,快取都沒有命中,於是都去請求了持久層資料庫。這會給持久層資料庫造成很大的壓力,這時候就相當於出現了快取穿透。 這裡需要注意和快取擊穿的區別,快取擊穿,是指一個key非常熱點,在不停的扛著大併發,大併發集中對這一個點進行訪問,當這個key在失效的瞬間,持續的大併發就穿破快取,直接請求資料庫,就像在一個屏障上鑿開了一個洞。 為了避免快取穿透其實有很多種解決方案。下面介紹幾種。 2、解決方案 (1)布隆過濾器 布隆過濾器是一種資料結構,垃圾網站和正常網站加起來全世界據統計也有幾十億個。網警要過濾這些垃圾網站,總不能到資料庫裡面一個一個去比較吧,這就可以使用布隆過濾器。假設我們儲存一億個垃圾網站地址。 可以先有一億個二進位制位元,然後網警用八個不同的隨機數產生器(F1,F2, …,F8) 產生八個資訊指紋(f1, f2, …, f8)。接下來用一個隨機數產生器 G 把這八個資訊指紋對映到 1 到1億中的八個自然數 g1, g2, …,g8。最後把這八個位置的二進位制全部設定為一。過程如下: 有一天網警查到了一個可疑的網站,想判斷一下是否是XX網站,首先將可疑網站通過雜湊對映到1億個位元陣列上的8個點。如果8個點的其中有一個點不為1,則可以判斷該元素一定不存在集合中。 那這個布隆過濾器是如何解決redis中的快取穿透呢?很簡單首先也是對所有可能查詢的引數以hash形式儲存,當用戶想要查詢的時候,使用布隆過濾器發現不在集合中,就直接丟棄,不再對持久層查詢。 這個形式很簡單。 2、快取空物件 當儲存層不命中後,即使返回的空物件也將其快取起來,同時會設定一個過期時間,之後再訪問這個資料將會從快取中獲取,保護了後端資料來源; 但是這種方法會存在兩個問題: 如果空值能夠被快取起來,這就意味著快取需要更多的空間儲存更多的鍵,因為這當中可能會有很多的空值的鍵;即使對空值設定了過期時間,還是會存在快取層和儲存層的資料會有一段時間視窗的不一致,這對於需要保持一致性的業務會有影響。 二、快取雪崩 1、概念 快取雪崩是指,快取層出現了錯誤,不能正常工作了。於是所有的請求都會達到儲存層,儲存層的呼叫量會暴增,造成儲存層也會掛掉的情況。 2、解決方案 (1)redis高可用 這個思想的含義是,既然redis有可能掛掉,那我多增設幾臺redis,這樣一臺掛掉之後其他的還可以繼續工作,其實就是搭建的叢集。 (2)限流降級 這個解決方案的思想是,在快取失效後,通過加鎖或者佇列來控制讀資料庫寫快取的執行緒數量。比如對某個key只允許一個執行緒查詢資料和寫快取,其他執行緒等待。 (3)資料預熱 資料加熱的含義就是在正式部署之前,我先把可能的資料先預先訪問一遍,這樣部分可能大量訪問的資料就會載入到快取中。在即將發生大併發訪問前手動觸發載入快取不同的key,設定不同的過期時間,讓快取失效的時間點儘量均勻。