快取雪崩#
快取雪崩:當大量快取資料在同一時間過期(失效)或者 Redis 故障宕機時,如果此時有大量的用戶請求,無法在 Redis 中處理,那麼這些請求將會直接訪問資料庫,從而導致資料庫壓力驟增,嚴重的話會導致資料庫崩潰宕機,進而導致整個系統崩潰。
解決方案:
- 避免為大量的資料設定成同一過期時間,我們可以在設定過期時間時添加一個隨機數,這樣就可以保證資料不會在同一時間過期了。
- 互斥鎖,如果發現訪問的資料不在 Redis 裡,就加個互斥鎖,保證同一時間內只有一個請求來構建快取(從資料庫讀取資料,再將資料更新到 Redis),當快取構建完成後,再釋放鎖。未能獲取到互斥鎖的請求,要麼等待鎖釋放後,重新讀取快取,要麼直接返回空值或者預設值。實現互斥鎖時,要設定超時時間,不然某個請求拿到鎖後,如果請求發生意外情況而一直阻塞,一直不釋放鎖,這時其他請求不能拿到鎖,整個系統就會出現無響應的現象。
- 後台更新快取,業務線程不再負責更新快取,快取不必設定有效期,讓快取 “永久有效”,並將更新快取的工作交由後台線程定時更新。
快取擊穿#
快取擊穿:如果快取中的某些熱點資料過期了,此時大量的請求訪問這些熱點資料,就無法從快取中讀取,進而直接訪問資料庫,導致資料庫被高併發請求沖垮。
解決方案:
- 互斥鎖,保證同一時間內只有一個線程更新快取,未能獲取到互斥鎖的請求,要麼等待鎖釋放,要麼直接返回空值或預設值。
- 不給熱點資料設定過期時間,由後台異步更新快取,或者在熱點資料要過期前,提前通知後台線程更新快取並重新設定過期時間。
快取穿透#
快取穿透:當用戶訪問的資料,既不在快取中,也不在資料庫中,導致請求在訪問快取時失效,再去訪問資料庫,發現資料庫中也沒有這些資料,沒辦法構建快取為後續的請求服務。當有大量這樣的請求時,資料庫的壓力會驟增,進而導致資料庫崩潰。
解決方案:
- 非法請求判斷:在請求入口處加入請求參數校驗,檢查參數是否合理有效,如果是非法參數,直接返回錯誤,避免進一步訪問快取和資料庫。
- 快取空值或預設值,針對某些要查詢的資料,在快取中設定一個空值或預設值,這樣後續的請求可以直接從快取中讀取到空值或者預設值,返回給應用程式,而不會進一步查詢資料庫。
- 布隆過濾器:當用戶請求到來時,可以通過查詢布隆過濾器來快速判斷資料是否存在,如果不存在,就不用再查詢資料庫了,這樣就能保證資料庫正常運行。