一、內存溢出淘汰策略redis
當redis的使用內存超過maxmemory時會觸發相應的策略,具體策略由maxmemory-policy參數控制算法
淘汰策略分爲六種:緩存
)noeviction:默認策略,此策略不會刪除任何數據;當客戶端還進行寫操做時將返回OOM(內存溢出)網絡
)volatile-lru:根據LRU算法刪除設置了過時時間的key,若是沒有可刪除的key,回退到noevication策略併發
)volatile-random:隨機刪除過時的keydom
)allkeys-lru:根據LRU算法從全部的key裏刪除分佈式
)allkeys-random:隨機算出全部的key函數
)volatile-ttl:根據對象ttl屬性刪除最近將要過時的key,若沒有回退到noevication策略spa
不推薦使用noevication、allkeys-lru線程
二、過時刪除
)惰性刪除:redis有一個專門存儲設置了過時時間的過時字典,每當客戶端要訪問一個key時,先回去這個過時字典裏查,若已過時則返回空;但僅只有這一個刪除策略的話就會致使一些長期未使用的key也佔用這內存,故有了一個定時刪除的策略
)定時刪除:redis內部維護了一個job,默認每10秒運行一次;它會根據key的過時比例,使用快慢兩種模式回收key
三、應用方刪除
)先從緩存讀取,獲取不到讀DB,而後再將DB讀到的數據寫入緩存
)先刪緩存,再更新DB(不推薦),怕併發寫操做致使髒數據
)先更新DB,再刪緩存(推薦)
究竟是緩存整個對象呢,仍是緩存須要的數據呢,咱們從兩個方面來分析:
一、緩存整個對象
優勢:通用性更好
缺點:浪費內存;網絡流量大,極端狀況可能會阻塞網絡;序列化和反序列化的CPU開銷更大
二、僅緩存須要使用的數據
優缺點與緩存整個對象偏偏相反,可是新增緩存屬性時須要修改代碼,並且修改後還須要刷新緩存
緩存穿透是指去訪問一個根本不可能不存在的key,緩存層和持久層都不會命中,從而致使請求直接打向持久層,增長持久層的壓力。
一、自身業務實現的問題
二、惡意攻擊、爬蟲等
一、緩存空對象
緩存空對象會有兩個問題:
)佔用更多的內存;緩存層會有更多的鍵,須要更多的內存;能夠經過設置過時時間解決問題
)數據不一致;若在緩存有效期時,持久層又新增了這一條數據,便會有這一問題;能夠經過MQ或其它方式清除緩存中的空對象
二、布隆過濾器
布隆過濾器其實是一個很長的二進制向量和一系列隨機映射函數。布隆過濾器能夠用於檢索一個元素是否在一個集合中。它的優勢是空間效率和查詢時間都遠遠超過通常的算法,缺點是有必定的誤識別率和刪除困難。它收到一個對key請求時先用布隆過濾器驗證是key否存在,若是存在在進入緩存層、存儲層。
可使用bitmap作布隆過濾器;但這種方式僅適用於數據命中不高、數據相對固定、實時性低的應用場景,代碼維護較爲複雜;優勢是緩存空間佔用少。
咱們都知道緩存層承載了大量的請求,它有效的保護了咱們的DB,但緩存層也可能由於某些狀況宕機了或大量緩存在同一時間失效,這樣便會致使大量請求直接到達DB,致使系統雪崩。
一、使用高可用的sentinel、cluster方案
二、採用多級緩存,如系統進程爲一級緩存,redis做爲二級緩存等等
三、緩存的過時時間隨機,不要讓大量緩存在同一時間失效
當一個熱點key過時時,剛好有大量的併發請求到這個key,此時這些併發請求就會大量的打入DB層。
出現緩存擊穿的緣由:
一、緩存中有熱點key
二、重建緩存不能再短時間內完成,如複雜計算或複雜SQL
一、分佈式互斥鎖
只容許線程重建一個緩存,其餘線程須要等待重建緩存的線程執行完後才能從新從緩存獲取數據。
二、永不過時
從緩存層面上看:不設置熱點key的過時時間
從功能層面上看:爲熱點key設置一個邏輯過時時間,當超過這個邏輯過時時間後,用一個單獨的線程將其緩存更新