redis 缺省會每秒進行十次過期掃瞄,過期掃瞄不會遍歷過期字典中所有的 key,而是採用了一種簡單的貪心策略。
從過期字典中隨機 20 個 key;
刪除這 20 個 key 中已經過期的 key;
如果過期的 key 比率超過 1/4,那就重複步驟 1;
同時,為了保證過期掃瞄不會出現迴圈過度,導致執行緒卡死現象,演算法還增加了掃瞄時間的上限,預設不會超過 25ms。
設想乙個大型的 redis 例項中所有的 key 在同一時間過期了,會出現怎樣的結果?
毫無疑問,redis 會持續掃瞄過期字典 (迴圈多次),直到過期字典中過期的 key 變得稀疏,才會停止 (迴圈次數明顯下降)。這就會導致線上讀寫請求出現明顯的卡頓現象。導致這種卡頓的另外一種原因是記憶體管理器需要頻繁**記憶體頁,這也會產生一定的 cpu 消耗。
當客戶端請求到來時,伺服器如果正好進入過期掃瞄狀態,客戶端的請求將會等待至少 25ms 後才會進行處理,如果客戶端將超時時間設定的比較短,比如 10ms,那麼就會出現大量的鏈結因為超時而關閉,業務端就會出現很多異常。而且這時你還無法從 redis 的 slowlog 中看到慢查詢記錄,因為慢查詢指的是邏輯處理過程慢,不包含等待時間。
所以業務開發人員一定要注意過期時間,如果有大批量的 key 過期,要給過期時間設定乙個隨機範圍,而不宜全部在同一時間過期,分散過期處理的壓力。
# 在目標過期時間上增加一天的隨機時間
redis.expire_at(key, random.randint(86400) + expire_ts)
在一些活動系統中,因為活動是一期一會,下一期活動舉辦時,前面幾期的很多資料都可以丟棄了,所以需要給相關的活動資料設定乙個過期時間,以減少不必要的 redis 記憶體占用。如果不加注意,你可能會將過期時間設定為活動結束時間再增加乙個常量的冗餘時間,如果參與活動的人數太多,就會導致大量的 key 同時過期。
掌閱服務端在開發過程中就曾出現過多次因為大量 key 同時過期導致的卡頓報警現象,通過將過期時間隨機化總是能很好地解決了這個問題,希望讀者們今後能少犯這樣的錯誤。
從庫不會進行過期掃瞄,從庫對過期的處理是被動的。主庫在 key 到期時,會在 aof 檔案裡增加一條del
指令,同步到所有的從庫,從庫通過執行這條del
指令來刪除過期的 key。
因為指令同步是非同步進行的,所以主庫過期的 key 的del
指令沒有及時同步到從庫的話,會出現主從資料的不一致,主庫沒有的資料在從庫里還存在,比如上一節的集群環境分布式鎖的演算法漏洞就是因為這個同步延遲產生的。
redis過期策略
1 noeviction 一旦記憶體滿則返回錯誤 2 allkeys lru 對所有的key進行lru 3 volatile lru 只對設定了過期的key進行lru 預設的方式 4 allkeys random 隨機剔除乙個key 5 volatile random 對設定過期的key進行隨機剔除...
Redis過期策略
1,設定過期時間 expire key time 單位為秒 setex string key,int seconds,string value 字串獨有的方式 注意 過期key的判定 檢查給定key是否存在於過期字典,如果存在,那麼取得key的過期時間。檢查當前unix時間戳是否大於key的過期時間...
redis過期策略
expire key second 這是常用的,以秒為單位 pexpire key millisecond 單位是毫秒 expireat key timestamp 將key的過期時間設定為timestamp代表的秒數的時間戳 pexpireat key millisecond timestamp ...