緩存相關的一些東西的總結
用redis做數據緩存:用戶訪問接口獲取數據時,先使用通過訪問redis獲取數據,若數據不存在,則通過訪問數據庫進行數據獲取
- 數據庫與redis做數據同步
- 強一致性:
- 通過redissession的讀寫鎖(存在性能瓶頸)
- 讀鎖:讀讀不互斥,讀寫互斥
- 寫鎖:讀寫互斥,寫寫互斥
- 延遲雙刪,操作數據庫完成后刪除緩存,等一段時間(主從同步時間),再次進行緩存刪除(嚴格說也是一種最終一致性)
- 延遲雙刪中,延遲的時間不好把握(在數據庫采用讀寫分離的情況下,不好把握數據同步到備節點的時間)
- 兩次刪除之間,請求有可能讀取到老的數據(第一次刪除后,完成主從同步前,讀取數據時,會讀取到老的數據)
- 只操作數據庫前刪除,操作數據庫后沒刪除:第一次刪除后,完成數據庫操作前,讀取數據時,會將老的數據寫入到緩存中
- 只操作數據庫后刪除,第一個線程讀取數據時,緩存恰好失效,讀取數據庫獲取最新數據(老數據),在此時,另一個線程恰巧在操作數據庫,若在數據庫操作完成,且刪緩存后,第一個線程將老數據寫入緩存中
- 通過redissession的讀寫鎖(存在性能瓶頸)
- 弱一致性(最終一致性)
- canal偽裝成MySQL的從節點,讀取binlog文件,進行數據同步(代碼侵入小)
- 服務將數據發送到MQ中,緩存服務讀取MQ進行數據同步
- 強一致性:
- 緩存穿透
- 用戶使用不存在的key進行數據獲取,導致查詢語句透傳到底層數據庫中,類似場景每次都直接訪問到數據庫,導致緩存不生效
- 緩存null值,若查不到,則在緩存中存null值,直接給用戶返回(會導致緩存污染,惡意攻擊時,會導致大量空值存在于緩存中)
- 使用布隆過濾器: 由于hash算法存在hash沖突問題,可能存在漏網之魚,若在更新布隆過濾器時,由于不可抗力因素導致更新失敗,可能導致部分正常數據被攔截
- 用戶使用不存在的key進行數據獲取,導致查詢語句透傳到底層數據庫中,類似場景每次都直接訪問到數據庫,導致緩存不生效
- 緩存擊穿
- 用戶在訪問數據時,當一個請求量很大時,該緩存恰好失效,導致大量請求涌入數據庫中進行查找
- 讀取數據庫操作增加互斥鎖:當一個請求訪問數據庫時,另外的請求等待,當寫入緩存后釋放鎖,其他請求直接從緩存中讀取數據
- 邏輯過期:讀取數據時,若發現數據已過期,使用新的線程觸發緩存更新,直接返回過期的緩存數據
- 熱點數據永不過期:使用定時任務刷新過期數據
- 增加本地緩存Caffeine或者Guava,當redis緩存失效時,優先訪問本地緩存
- 若壓力過大,可以采用熔斷機制,返回默認值或錯誤
- 用戶在訪問數據時,當一個請求量很大時,該緩存恰好失效,導致大量請求涌入數據庫中進行查找
- 緩存雪崩:
- 當主緩存中,數據大量同時失效,進行數據庫訪問
- 增加本地緩存Caffeine或者Guava進行緩解壓力
- 緩存失效時間隨機化
- 熔斷,返回默認值或錯誤
- 使用分布式鎖重建緩存,當一個請求讀取緩存時,其他請求等待,直接讀取緩存中的數據
- 增加本地緩存Caffeine或者Guava進行緩解壓力
- 當主緩存中,數據大量同時失效,進行數據庫訪問

浙公網安備 33010602011771號