快取淘汰、快取穿透、快取擊穿、快取雪崩、資料庫快取雙寫一致性

Java學習錄發表於2019-04-28

快取淘汰

為什麼需要快取淘汰?你需要快取30G的資料,但是Redis本身只能使用10G的記憶體,那你就得做個取捨了,畢竟魚與熊掌不可兼得。為了利益最大化肯定要保留最重要的10個G。



Redis本身提供了6中快取淘汰策略,以下屬性表示允許使用的最大記憶體

server.maxmemory複製程式碼

當使用的記憶體超過限制記憶體時,Redis會根據配置的以下6中淘汰策略選擇資料淘汰

  • volatile-lru:從已設定過期時間的資料集中挑選最近最少使用的資料淘汰

  • volatile-ttl:從已設定過期時間的資料集挑選將要過期的資料淘汰

  • volatile-random:從已設定過期時間的資料集中任意選擇資料淘汰

  • allkeys-lru:從資料集中挑選最近最少使用的資料淘汰

  • allkeys-random:從資料集中任意選擇資料淘汰

  • no-enviction:記憶體不足時新增資料會報錯(沒人用這個吧?)

其他相關配置:

#指定資料淘汰演算法
maxmemory-policy allkeys-lru
#LRU和最小TTL演算法的樣本個數
maxmemory-samples 5複製程式碼

快取穿透

大量的請求瞬時湧入系統,而這個資料在Redis中不存在,從而所有的請求都落到了資料庫上從而把資料庫打死。造成這種情況的原因如下:

  • 系統設計不合理,快取資料更新不及時

  • 爬蟲等惡意攻擊

解決方案:

  • 如果key在資料庫中也不存在,那麼就寫一個空值到Redis中,並設定一個過期時間,避免一直佔用記憶體

  • 查詢快取之前使用布隆過濾器攔截

快取擊穿

快取擊穿,就是常說的熱點key問題,當一個正有非常巨大的訪問量訪問的key 在失效的瞬間,大量的請求擊穿了快取,直接落到了資料庫上,然後所有從資料獲取到資料的執行緒又都併發的想要把資料快取到redis中。


解決方案:

  • 使用互斥鎖,同一時刻只允許一個執行緒去構建快取,其他執行緒等待構建完畢後去快取取

  • 定時更新,假如快取過期時間為60分鐘,則單獨設定一個執行緒每59分鐘去負責更新快取


快取雪崩

由於Redis是基於記憶體的應用,可以很容易做到高效能、高併發從而起到保護資料庫的作用。如果快取意外掛了、所有的請求落到了資料上就形成了快取雪崩。

解決方案:


資料庫快取雙寫一致性

當一個資料需要更新時因為不可能做到同時更新資料庫和快取、那麼此時讀取資料的時候就一定會發生資料不一致問題,而資料不一致問題在金融交易領域的系統中是肯定不允許的。


解決方案:

  • 讀的時候,先讀快取,快取沒有的話,就讀資料庫,然後取出資料後放入快取,同時返回響應。

  • 更新的時候,先更新資料庫,然後再刪除快取。


參考自公眾號:石杉的架構筆記



快取淘汰、快取穿透、快取擊穿、快取雪崩、資料庫快取雙寫一致性


相關文章