1. 程式人生 > 資料庫 >三、Redis快取問題

三、Redis快取問題

三、Redis快取問題

    Redis快取的使用,極大的提升了應用程式的效能和效率,特別是資料查詢方面。但同時,它也帶來了一些問題。其中,最要害的問題,就是資料的一致性問題,從嚴格意義上講,這個問題無解。如果對資料的一致性要求很高,那麼就不能使用快取。

    1、快取擊穿(熱點的key,大併發)

        (1)、現象:快取擊穿,是指一個key非常熱點,在不停的扛著大併發,大併發集中對這一個點進行訪問,當這個key在失效的瞬間,持續的大併發就穿破快取,直接請求資料庫,就像在一個屏障上鑿開了一個洞。做電商專案的時候,把這貨就稱為“爆款”。

        (2)、解決方案:

            方案一:

在快取失效的時候(判斷拿出來的值為空),不是立即去load db,而是先利用Redis的分散式鎖功能去加鎖,當操作返回成功時,再進行load db的操作並回設快取;否則可能同時候的其他程序已經load db並回設到快取了,這時候重試get快取的方法。

            方案二:大多數情況下這種爆款很難對資料庫伺服器造成壓垮性的壓力。達到這個級別的公司沒有幾家的。所以,對主打商品都是早早的做好了準備,讓快取永不過期。即便某些商品自己發酵成了爆款,也是直接設為永不過期就好了。

    2、快取穿透(某個key查詢為空,未做快取處理)

        (1)、現象:快取穿透是指查詢一個數據庫一定不存在的key,請求量很大,如果資料庫查詢物件為空,則不放進快取。

        (2)、解決方案:

            方案一:最常見的是採用布隆過濾器,布隆過濾器是一種資料結構,將所有可能存在的資料雜湊到一個足夠大的bitmap中,一個一定不存在的資料會被這個bitmap攔截掉,從而避免了對底層儲存系統的查詢壓力。

            方案二:如果從資料庫查詢的物件為空,也放入快取,只是設定的快取過期時間較短,最長不超過五分鐘。如果空值能夠被快取起來,這就意味著快取空間需要儲存更多的鍵,因為這當中可能會有很多空值的鍵。

    3、快取雪崩(大量的key)

        (1)、現象:是指在某一個時間段,快取集中過期失效。

            原因一:

資料在某個時間段比較集中的放入了快取,假設快取一個小時。一小時過後,這批資料的快取就都過期了,而此時對這批資料的訪問查詢,都落到了資料庫上,對於資料庫而言,就會產生週期性的壓力波峰。

            原因二:快取伺服器某個節點宕機或斷網,對資料庫伺服器造成的壓力是不可預知的,很有可能瞬間就把資料庫壓垮。

        (2)、解決方案:

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

            注意:加鎖排隊的解決方式分散式環境的併發問題,有可能還要解決分散式鎖的問題;執行緒還會被阻塞,使用者體驗很差。因此,在真正的高併發場景下很少使用。

            方案二:做二級快取,A1為原始快取,A2為拷貝快取,A1失效時,可以訪問A2,A1快取失效時間設定為短期,A2設定為長期

            方案三:不同的key,設定不同的過期時間,讓快取失效的時間點儘量均勻。