快取淘汰
為什麼需要快取淘汰?你需要快取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是基於記憶體的應用,可以很容易做到高效能、高併發從而起到保護資料庫的作用。如果快取意外掛了、所有的請求落到了資料上就形成了快取雪崩。
解決方案:
事前:使用主從複製+哨兵或者Redis叢集。Redis主從複製、Redis的哨兵機制、Redis叢集環境搭建
事中:本地快取結合限流和降級。基於註解的分散式限流元件
事後:開啟持久化配置,實現快速快取的快速恢復。 Redis 的持久化機制
資料庫快取雙寫一致性
當一個資料需要更新時因為不可能做到同時更新資料庫和快取、那麼此時讀取資料的時候就一定會發生資料不一致問題,而資料不一致問題在金融交易領域的系統中是肯定不允許的。
解決方案:
讀的時候,先讀快取,快取沒有的話,就讀資料庫,然後取出資料後放入快取,同時返回響應。
更新的時候,先更新資料庫,然後再刪除快取。
參考自公眾號:石杉的架構筆記