所有 Redis 資料結構均支援設定過期時間,當時間到期時,Redis 會自動刪除該資料結構。你可以想像 Redis 內部有一個死神,時刻盯著所有設定了過期時間的 key,壽命一到就會立即收割。
你可以考慮從死神的視角出發,是否因為太多的 key 同時過期而導致無法處理。同時因為 Redis 是單線程的,收割的時間也會佔用線程的處理時間,如果收割的太過於繁忙,會不會導致線上讀寫指令出現卡頓。
redis 會將每個設定了過期時間的 key 放入到一個獨立的字典中,以後會定時遍歷這個字典來刪除到期的 key。除了定時遍歷之外,它還會使用惰性策略來刪除過期的 key,所謂惰性策略就是在客戶端存取這個 key 的時候,redis 會對 key 的過期時間進行檢查,如果過期了就立即刪除。定時刪除是集中處理,惰性刪除是零散處理。
Redis 預設會每秒進行十次過期掃描,過期掃描不會遍歷過期字典中所有的 key,而是採用了一種簡單的貪心策略。
從過期字典中隨機20 個key;
刪除這20 個key 中已經過期的key;
如果過期的key 比率超過1/4,那就重複步驟1;
同時,為了確保過期掃描不會出現循環過度,導致線程卡死現象,演算法還增加了掃描時間的上限,預設不會超過25ms。
設想一個大型的 Redis 實例中所有的 key 在同一時間過期了,會出現怎樣的結果?
毫無疑問,Redis 會持續掃描過期字典 (循環多次),直到過期字典中過期的 key 變得稀疏,才會停止 (循環次數明顯下降)。這就會導致線上讀寫請求出現明顯的卡頓現象。另一個導致卡頓的原因是記憶體管理器需要頻繁回收記憶體頁,這也會帶來一定的 CPU 消耗。
當客戶端請求到來時,伺服器如果剛好進入過期掃描狀態,客戶端的請求將會等待至少25ms 後才會進行處理,如果客戶端將逾時時間設定的比較短;
如果逾時時間設定為10ms,會導致大量連線因為逾時而關閉,從而使業務端出現大量異常。而且這時你還無法從 Redis 的 slowlog 中看到慢查詢記錄,因為慢查詢指的是邏輯處理過程慢,不包含等待時間。
以上是redis過期策略有哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!