redis 過期策略你知道多少,看完文章你會不自覺說喔哦
Redis 所有的數據結構都可以設置過期時間,時間一到,就會自動刪除。你可以想像 Redis 內部有一個死神,時刻盯着所有設置了過期時間的 key,壽命一到就會立即收割。
你還可以進一步站在死神的角度思考,會不會因為同一時間太多的 key 過期,以至於忙不過來。同時因為 Redis 是單線程的,收割的時間也會佔用線程的處理時間,如果收割的太過於繁忙,會不會導致線上讀寫指令出現卡頓。
這些問題 Antirez 早就想到了,所有在過期這件事上,Redis 非常小心。
過期的 key 集合
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 中看到慢查詢記錄,因為慢查詢指的是邏輯處理過程慢,不包含等待時間。
所以業務開發人員一定要注意過期時間,如果有大批量的 key 過期,要給過期時間設置一個隨機範圍,而不宜全部在同一時間過期,分散過期處理的…
以上內容希望幫助到大家,很多PHPer在進階的時候總會遇到一些問題和瓶頸,業務代碼寫多了沒有方向感,不知道該從那裡入手去提升,對此我整理了一些資料,包括但不限於:分佈式架構、高可擴展、高性能、高並發、服務器性能調優、Redis、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階乾貨需要的可以免費分享給大家
相應的文章已經整理形成文檔,git掃碼獲取資料看這裡