快取雪崩就是 redis 的大量熱點資料在短時間內同時過期(失效),因為設定了相同的過期時間,剛好這個時候 redis 請求的併發量又很大,就會導致所有的請求到資料庫。
快取雪崩解決方案:
1. 加互斥鎖或者使用佇列,針對同乙個key只允許乙個執行緒到資料庫查詢;
2.快取定時預先更新,避免同時失效;
3.通過加隨機數,使 key 在不同的時間過期,錯開過期時間;
4.快取永不過期。
快取穿透是說請求查詢的key在redis快取和資料庫都不存在,這可能是一次錯誤的查詢,也可能使用者惡意攻擊。在這種情況下,因為資料庫值不存在,所以肯定不會寫入 redis,那麼下一次查詢相同的key 的時候,肯定還是會再到資料庫查一次。這種頻繁查詢資料庫中不存在的值,導致redis快取失效,我們稱之為快取穿透。
避免快取穿透解決方案:
1.根據key快取空資料,同時必須設定乙個過期時間;
2.根據key快取特殊字串;
3.根據ip做限流。
每次查詢的key如果我們知道在資料庫不存在,我們直接返回就不需要到資料庫查詢。我們可以考慮布隆過濾器,我們把key放入到bitmap中,根據布隆過濾器特性,判斷key不存在則key在資料庫中一定不存在,這樣我們就可以有效的過濾不合法的查詢請求了。
3.1、查詢請求,redis中不存在,則先到資料庫查詢然後放入快取,redis存在則直接返回。
3.2、更新請求,先刪除快取還是先更新資料庫?
如果先刪除了快取,但更新資料庫還沒有完成,這是另乙個查詢請求查詢相同key,發現快取沒有,就會從資料庫查詢,然後將redis中放乙份。這樣刪除就失效的。所以要先更新資料庫。
3.3、是刪除快取還是更新快取的值呢?
更新快取之前,是不是要經過其他表的查詢、介面呼叫、計算才能得到最新的資料,而不是直接從資料庫拿到的值。如果是的話,建議直接刪除快取,這種方案更加簡單,而且避免了資料庫的資料和快取不一致的情況。在一般情況下,我們也推薦使用刪除的方案。另外根據懶載入思想,我們可以等到查詢時在重新放乙份到redis中,而不是更新快取。
redis的資料與資料庫不可能通過事務達到統一,我們只能通過一些措施降低出現不一致的概率。
(1)如果更新資料庫失敗,刪除快取成功與否,下次查詢獲取的資料都是舊值。當更新資料庫失敗時捕獲異常,不操作快取,所以這時資料依然一致。
(2)如果更新資料庫成功,刪除快取失敗,則快取與資料庫不一致。出現這種情況我們如何解決呢?
第一種:刪除快取失敗後增加重試機制,將要刪除的key放入訊息佇列,通過執行緒消費佇列再去刪除這個key。
第二種:採用非同步更新快取,因為更新資料庫時會往 binlog 寫入日誌,所以我們可以通過乙個服務來監聽 binlog的變化(比如阿里的 canal),然後在客戶端完成刪除 key 的操作。如果刪除失敗的話,再傳送到訊息佇列。總之,對於後刪除快取失敗的情況,我們的做法是不斷地重試刪除,直到成功。無論是重試還是非同步刪除,都是最終一致性的思想。
(3)如果二者均成功則完美。
3.4 延時雙刪
前面我們說到先刪快取再更新資料庫可能存在刪除了又被另乙個請求從資料庫拿出來放入快取。那麼我們又想到改進的方案:延時雙刪。步驟如下:
1.先刪除快取,2.更新資料庫,3.執行緒休眠一會兒,4,再刪除一遍。
Redis 快取問題
描述 查詢乙個資料庫中不存在的資料,比如商品詳情,查詢乙個不存在的id,每次都會訪問db,如果有人惡意破壞,很可能直接對db造成過大地壓力。解決方案 當通過某乙個key去查詢資料的時候,如果對應在資料庫中的資料都不存在,我們將此key對應的value設定為乙個預設的值,比如 null 並設定乙個快取...
Redis快取問題
1.快取雪崩 快取雪崩是指快取同一時間大面積的失效,所以後面的請求都會落到資料庫上,造成資料庫短時間內承受大量請求而崩掉。解決方案 快取資料過期時間隨機設定,防止同一時間大量資料過期現象發生。併發量不是特別多的時候,加鎖排隊。給每乙個快取資料新增乙個標價,記錄快取是否失效,如果失效,則更新資料快取。...
Redis快取穿透 快取雪崩問題
穿透雪崩主要是因為查詢資料庫造成的,那麼讀寫分離,快取資料查詢失敗不去查資料庫就好了。查的時候有即是有,無即是無,不會再查資料庫,快取的穿透和雪崩問題就不存在了。其次新增資料庫和快取同步功能,保證資料庫和快取資料是一致的即可 需要注意的是這時候資料庫資料是有限和相對穩定的,其實如果是海量資料同時放入...