懶惰處理
Redis在get操作時遇到過期的key會進行刪除操作。
集中處理
Redis會將設置了過期時間的key放到壹個獨立的字典裏,默認每秒10次過期掃描。掃描方式:
為防止掃描時間過長,掃描時間限制為25ms,開發時應盡量避免大量key同時過期。
從庫不會進行過期掃描,主庫刪除時,會在AOF文件裏增加壹條del指令,同步到所有從庫,從庫通過此指令來刪除。由於指令的同步存在異步,所以會出現主從數據不壹致的情況。
當Redis內存超出物理內存限制時,內存數據會開始和磁盤產生頻繁的交換,使得性能急劇下降。為了限制內存的使用,Redis提供參數 maxmemory 來限制最大內存,當內存超出後,會有以下策略( maxmemory-policy )來淘汰key以騰出空間:
由於LRU算法需要消耗大量的額外內存,redis采用壹種近似的LRU算法。它給每個 key 增加了壹個額外的小字段(24bit),也就是最後壹次被訪問的時間戳。每次執行寫操作時,如果發現內存超出 maxmemory ,就隨機采樣5個(參數 maxmemory_samples 配置)key,然後淘汰最舊的。如果淘汰之後還是超出,那就繼續隨機淘汰,直到不超出為止。如果 maxmemory-policy 是volatile-xxx,就從設置過期時間的key裏采樣,否則就從所有key裏采樣。
Redis3.0裏增加了壹個淘汰池,就是壹個大小為 maxmemory_samples 的數組。每次淘汰時會將隨機出來的key和數組裏的key融合,淘汰掉最舊的壹個,然後將剩下的較舊的key放到淘汰池裏給下個循環用。
redis的刪除del在刪除壹個大對象的時候有可能造成卡頓。為了解決這個問題Redis4.0引入了unlink指令,將這個key的對象引用從Redis內存數據裏刪除,將刪除操作封裝成壹個任務丟到壹個異步隊列裏。然後有個異步線程會從這個隊列裏取出任務並執行。
清空操作 flushdb 和 flushall ,在Redis4.0後,在指令後面增加 async ,就也可以像上面壹樣異步執行。
《Redis深度歷險:核心原理和應用實踐》