Redis 服務器將所有的資料庫都保存在服務器狀態redisServer結構的db陣列中,db陣列的每個項都是一個redisDB:
struct redisServer{ //一個陣列保存著服務器中的所有資料庫 redisDb *db; //資料庫的個數 int dbnum; }
dbnum:服務器初始化時,程式根據dbnum 來決定應創建多少少資料庫,由服務器配置的database選項決定,默認16.
在服務器內部,客戶端狀態redisClient結構的db屬性記錄了客戶端當前目標資料庫,這個屬性指向redisDb結構的指標:
typedef struct redisClient{ //記錄客戶端當前正在使用的資料庫 redisDb *db; } redisClient;
redisClient指標指向redisServer 陣列的其中一個元素,而被指向的元素就是客戶端的目標資料庫,

redisBd結構的dict地點保存了資料庫中的所有鍵值對,我們將這個字典稱為鍵空間,
鍵空間的鍵也就是資料庫的鍵,每個鍵都是一個字串物件,
鍵空間的值也是資料庫的值,每個值可以是字串物件、串列物件、哈希表物件、集合物件和有序集合物件中的任意一種Redis物件,
Redis命令對資料庫進行讀寫時,服務器不僅對鍵執行指定的讀寫操作,還會執行一些額外的維護作業:
1、讀取一個鍵后,服務器會根據鍵是否存在來更新服務器鍵空間命中次數或鍵空間不命中次數,
2、讀取一個鍵之后,服務器會更新鍵的LRU(最后一次使用時間),這個值用于計算鍵的空閑時間,
3、如果服務器在讀取一個鍵時發現該鍵已經過期,那么服務器會先洗掉這個過期鍵,然后再執行余下的操作,
4、如果客戶端使用Watch命令監視某個鍵,那么服務器再對被監視的鍵進行修改后,會將這個鍵標記為臟,從而讓事務程式注意到這個鍵已經被修改過,
5、服務器每次修改一個鍵之后,都會對臟鍵計數器的值加一,這個計數器會觸發服務器的持久化以及賦值操作,
6、如果服務器開啟了資料庫通知功能,那么在對鍵進行修改后,服務器將按配置發送相應的資料庫通知,
設定過期時間:
命令 EXPIRE key ttl 設定鍵生存時間為ttl秒
命令 PEXPIRE key ttl 設定鍵生存時間為ttl毫秒
命令EXPIREAT key timestamp 命令 設定鍵key過期時間為timestamp秒數時間戳
命令 PEXPIREAT key timestamp 設定鍵key過期時間為timestamp所指定的毫秒時間戳
1、EXPIRE命令可以轉換為 PEXPIRE命令
def EXPIRE(key,ttl_in_sec); ttl_in_ms = sec_to_ms(ttl_in_sec) PEXPIRE(key,ttl_in_ms)
2、PEXPIRE命令轉換為PEXPIREAT命令
def PEXPIRE(key,ttl_in_ms) now_ms = get_current_unix_timestamp_in_ms(); PEXPIREAT(key,now_ms+ttl_in_ms)
3、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字典保存了資料庫所在鍵的過期時間(過期字典),
1、過期字典的鍵是一個指標指向鍵空間的某個鍵物件,
2、過期字典的值是一個long型別的整數(毫秒精度的UNIX時間戳),
過期洗掉策略
1、定時洗掉,在設定過期時間的同時,創建定時器,到期立即洗掉(記憶體友好,CPU不友好),
2、惰性洗掉,下一次查詢時,查詢是否過期,過期洗掉,(記憶體不友好,CPU友好),
3、定期洗掉,每隔一段時間執行一次,
Redis的洗掉策略使用了 惰性洗掉和定期洗掉兩種,
在執行SAVE或者BGSAVE命令生成RDB檔案時,程式會對資料庫中的鍵進行檢查,已過期的鍵不會被保存到新創建的RDB檔案中,因此資料庫包含過期鍵不會對新生成的RDB檔案造成影響,
在載入RDB檔案時,如果服務器以主服務器模式運行,載入RDB檔案時會對鍵進行檢查,未過期的鍵加載到資料庫中,過期鍵忽略,從服務器模式運行時,檔案中保存的所有鍵被加載,主從同步時,從服務器過期鍵被清空,
AOF檔案寫入時,如果過期鍵未清理,AOF檔案不會因為過期鍵而產生影響,過期鍵被洗掉后,程式會向AOF檔案追加DEL命令,來顯示的記錄該鍵已被洗掉,
AOF重寫時,程式會對資料庫中的鍵檢查,已過期的鍵不會被保存到重寫后的AOF檔案中,
服務器在復制模式下,服務器的過期鍵由主服務器控制:主服務器在洗掉過期鍵后會向從服務器發送一條DEL命令,從服務在未收到命令前,客戶端的讀命令會像對未過期鍵處理方式一樣,直到接到DEL命令,從過期鍵才會洗掉,
每天學一點,總會有識訓,
說明:尊重作者知識產權,文中內容參考《Redis設計與實作》,僅在此做學習與大家分享,

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/3175.html
標籤:NoSQL
