設置鍵過期時間的命令
- EXPIRE
- PEXPIRE
- EXPIREAT
- PEXPIREAT
保存鍵的過期時間
在redisDb中,用一個名為expire的字典保存了所有鍵的過期時間,稱它為過期字典。
- 過期字典的鍵是一個指針,指向了鍵空間的某個數(shù)據(jù)庫鍵對象
- 過期字典的值是一個long long類型,保存了數(shù)據(jù)庫鍵的過期時間,即一個毫秒精度的unix時間戳
/* Redis database representation. There are multiple databases identified * by integers from 0 (the default database) up to the max configured * database. The database number is the 'id' field in the structure. */ typedef struct redisDb { dict *dict; /* The keyspace for this DB */ dict *expires; /* Timeout of keys with a timeout set */ ...... } redisDb;
過期鍵的判定
- 檢測過期字典里是否存在鍵,如果不存在則返回false,存在則取過期時間
- 檢測當前unix時間戳是否大于過期時間,大于表示鍵過期,否則未過期
過期鍵刪除策略
定時刪除
設置鍵過期時間的同時,設置一個定時器在過期時間來臨時刪除鍵
- 優(yōu)點是保證了過期鍵會盡可能快的刪掉,釋放占用的內存
- 刪除操作會占用cpu時間,在有大量鍵需要刪除,而內存不緊張但cpu時間緊張的情況下,會對響應時間和吞吐量造成影響
惰性刪除
放任過期鍵不管,每次獲取鍵時都得檢查是否過期,過期則刪除,未過期則返回值
- 優(yōu)點是對cpu時間優(yōu)化,保證只有在非做不可的時候才會刪除,而不會在其它無關的過期鍵浪費時間
- 缺點是對內存不友好,如果存在非常多的過期鍵會占用大量內存
定期刪除
每隔一段時間,對數(shù)據(jù)庫檢查刪除過期鍵,而刪除多少,檢查多少個數(shù)據(jù)庫由算法決定。定期刪除實際上是上面兩種算法的折中。
- 優(yōu)點是可以限制刪除操作執(zhí)行的時長和頻次,減少對cpu時間的影響;定期刪除能有效減少內存浪費
- 缺點是難以確定時長和頻次,如果刪除太頻繁或者執(zhí)行時間太長,會占用cpu資源;如果刪除頻次太少或者執(zhí)行時間太短,又會造成內存浪費
redis的刪除策略,惰性刪除和定期刪除的結合
惰性刪除的實現(xiàn)
所有讀寫數(shù)據(jù)庫的redis命令執(zhí)行前,都會調用expireIfNeeded函數(shù)來做檢查,如果輸入鍵未過期則不做處理,如果過期則expireIfNeeded函數(shù)將它刪除
定期刪除的實現(xiàn)
周期性調用activeExpireCycle函數(shù),分多次遍歷服務器中的各個數(shù)據(jù)庫,從數(shù)據(jù)庫字典中隨機檢查一部分鍵的過期時間,并且刪除其中的過期鍵
過期鍵對RDB,AOF,復制的影響
RDB
- 生成RDB文件時,已過期的鍵不會保存
- 載入RDB文件時,如果是主服務器不會載入過期鍵,如果是從服務器會載入,因為主從復制時從服務器也會清空
AOF
- AOF文件寫入時,當過期鍵被刪除時,會向AOF文件追加一條DEL命令顯示刪除該記錄
- AOF文件重寫時,過期鍵不會重寫到AOF文件中
復制
在復制模式下,從服務器的過期刪除動作由主服務器控制 - 主服務器刪除過期鍵,會顯示通知所有從服務器刪除,通過發(fā)送DEL命令的方式
- 從服務器執(zhí)行讀命令時碰到過期鍵不會惰性刪除,而是會返回數(shù)據(jù)給客戶端
- 從服務器只有接收了DEL命令時,才會刪除過期鍵