Redis 服務器將全部的數據庫都保存在服務器狀態redisServer結構的db數組中,db數組的每一個項都是一個redisDB:redis
struct redisServer{ //一個數組保存着服務器中的全部數據庫 redisDb *db; //數據庫的個數 int dbnum; }
dbnum:服務器初始化時,程序根據dbnum 來決定應建立多少少數據庫,由服務器配置的database選項決定,默認16.數據庫
在服務器內部,客戶端狀態redisClient結構的db屬性記錄了客戶端當前目標數據庫,這個屬性指向redisDb結構的指針:數組
typedef struct redisClient{ //記錄客戶端當前正在使用的數據庫 redisDb *db; } redisClient;
redisClient指針指向redisServer 數組的其中一個元素,而被指向的元素就是客戶端的目標數據庫。服務器
redisBd結構的dict地點保存了數據庫中的全部鍵值對,咱們將這個字典稱爲鍵空間。學習
鍵空間的鍵也就是數據庫的鍵,每一個鍵都是一個字符串對象。spa
鍵空間的值也是數據庫的值,每一個值能夠是字符串對象、列表對象、哈希表對象、集合對象和有序集合對象中的任意一種Redis對象。設計
Redis命令對數據庫進行讀寫時,服務器不只對鍵執行指定的讀寫操做,還會執行一些額外的維護工做:unix
一、讀取一個鍵後,服務器會根據鍵是否存在來更新服務器鍵空間命中次數或鍵空間不命中次數。指針
二、讀取一個鍵以後,服務器會更新鍵的LRU(最後一次使用時間),這個值用於計算鍵的空閒時間。code
三、若是服務器在讀取一個鍵時發現該鍵已通過期,那麼服務器會先刪除這個過時鍵,而後再執行餘下的操做。
四、若是客戶端使用Watch命令監視某個鍵,那麼服務器再對被監視的鍵進行修改後,會將這個鍵標記爲髒,從而讓事務程序注意到這個鍵已經被修改過。
五、服務器每次修改一個鍵以後,都會對髒鍵計數器的值加一,這個計數器會觸發服務器的持久化以及賦值操做。
六、若是服務器開啓了數據庫通知功能,那麼在對鍵進行修改後,服務器將按配置發送相應的數據庫通知。
設置過時時間:
命令 EXPIRE key ttl 設置鍵生存時間爲ttl秒
命令 PEXPIRE key ttl 設置鍵生存時間爲ttl毫秒
命令EXPIREAT key timestamp 命令 設置鍵key過時時間爲timestamp秒數時間戳
命令 PEXPIREAT key timestamp 設置鍵key過時時間爲timestamp所指定的毫秒時間戳
一、EXPIRE命令能夠轉換爲 PEXPIRE命令
def EXPIRE(key,ttl_in_sec); ttl_in_ms = sec_to_ms(ttl_in_sec) PEXPIRE(key,ttl_in_ms)
二、PEXPIRE命令轉換爲PEXPIREAT命令
def PEXPIRE(key,ttl_in_ms) now_ms = get_current_unix_timestamp_in_ms(); PEXPIREAT(key,now_ms+ttl_in_ms)
三、EXPIREAT命令轉換爲PEXPIREAT命令
def EXPIREAT(key,expire_time_in_asc) expire_time_in_ms = sec_to_ms(expire_time_in_sec) PEXPIREAT(key,expire_time_in_ms)
redisDB 結構的expires字典保存了數據庫所在鍵的過時時間(過時字典),
一、過時字典的鍵是一個指針指向鍵空間的某個鍵對象。
二、過時字典的值是一個long類型的整數(毫秒精度的UNIX時間戳)。
過時刪除策略
一、定時刪除,在設置過時時間的同時,建立定時器,到期當即刪除(內存友好,CPU不友好)。
二、惰性刪除,下一次查詢時,查詢是否過時,過時刪除,(內存不友好,CPU友好)。
三、按期刪除,每隔一段時間執行一次。
Redis的刪除策略使用了 惰性刪除和按期刪除兩種。
在執行SAVE或者BGSAVE命令生成RDB文件時,程序會對數據庫中的鍵進行檢查,已過時的鍵不會被保存到新建立的RDB文件中,所以數據庫包含過時鍵不會對新生成的RDB文件形成影響。
在載入RDB文件時,若是服務器以主服務器模式運行,載入RDB文件時會對鍵進行檢查,未過時的鍵加載到數據庫中,過時鍵忽略。從服務器模式運行時,文件中保存的全部鍵被加載,主從同步時,從服務器過時鍵被清空。
AOF文件寫入時,若是過時鍵未清理,AOF文件不會由於過時鍵而產生影響,過時鍵被刪除後,程序會向AOF文件追加DEL命令,來顯示的記錄該鍵已被刪除。
AOF重寫時,程序會對數據庫中的鍵檢查,已過時的鍵不會被保存到重寫後的AOF文件中。
服務器在複製模式下,服務器的過時鍵由主服務器控制:主服務器在刪除過時鍵後會向從服務器發送一條DEL命令,從服務在未收到命令前,客戶端的讀命令會像對未過時鍵處理方式同樣,直到接到DEL命令,從過時鍵纔會刪除。
天天學一點,總會有收穫。
說明:尊重做者知識產權,文中內容參考《Redis設計與實現》,僅在此作學習與你們分享。