一、redis的過期策略
定期刪除+惰性刪除
redis在存儲數據時,可能會設置過期時間,而所謂的定期刪除,指的是redis默認是每隔100ms就隨機抽取一些設置了過期時間的key進行檢查,如果過期了就會刪除。
至于為啥是每隔100ms隨機抽取一些數據進行檢查而不是全部檢查,這就與cpu負載有關了,如redis中的數據十分龐大,并且全部都設置了過期時間,依次全部檢查并且進行刪除的話負載太高,影響性能。
但是,由于是隨機抽取的key進行檢查進行刪除,那么很多的key可能會到了過期時間了還沒進行刪除,那么怎么辦呢?這時候,惰性刪除就會發(fā)揮作用了,所謂的惰性刪除,就是在讀取某個key的時候,redis會先檢查一個該key是否過期,如果過期了,就會在此時刪除,然后不會給你返回任何東西。
但是此時就會產生另外一個問題,假如一些key設置了過期時間,而定期刪除的隨機抽取沒有選中這些key,而恰好也沒有人去獲取這些key,惰性刪除也發(fā)揮不了作用了,那么這些數據就會越積累越多,redis一般作為緩存的,是基于內存的,這些數據越來越多的時候回導致內存耗盡,影響性能,這時候應該怎么辦呢?這時候,另一個重量型的武器就要發(fā)揮作用了,那就是:內存淘汰機制。
AOF、RDB和復制功能對過期key的處理
在執(zhí)行save或bgsave命令創(chuàng)建一個新的RDB文件時,redis會對鍵進行檢查,已過期的鍵不會保存到RDB文件中。當啟用了rdb持久化策略,在啟用redis時,服務器會對rdb文件進行載入。
如果是主庫,載入rdb文件時,會對鍵進行檢查,已過期的鍵不會載入到redis中。如果是從庫載入rdb文件時,不論key是否過期,都會被載入到redis中,但這不會對redis造成影響。因為主從服務器進行數據同步時,從數據庫的數據會被清空。
當redis使用aof持久化策略,當redis刪除一條過期key時,會同時向aof文件中追加一條del命令。在執(zhí)行aof重寫的過程中,程序會對數據庫中的鍵進行檢查,已過期的建不會被保存到重寫的aof文件中。
當服務器運行在復制模式下時,從服務器的過期鍵刪除動作有主服務器控制,所以讀寫分離模式下,會出現(xiàn)key過期但仍有效的問題。(reidis3.2已修復)
二、內存淘汰機制 (maxmemory-policy)
- noeviction: (默認策略) 當內存不足以容納新寫入數據時,新寫入操作會報錯。
- allkeys-lru:當內存不足以容納新寫入數據時,在鍵空間中,移除最近最少使用的 key。
- allkeys-random:當內存不足以容納新寫入數據時,在鍵空間中,隨機移除某個 key。
- volatile-lru:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,移除最近最少使用的 key。
- volatile-random:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,隨機移除某個 key。
- volatile-ttl:當內存不足以容納新寫入數據時,在設置了過期時間的鍵空間中,有更早過期時間的 key 優(yōu)先移除。