數據庫
Redis服務器的所有數據庫都保存在redisServer.db數組中,而數據庫的數量則由redisServer.dbnum屬性保存。
struct redisServer {
// ..
// 一個數組,保存着服務器中的所有數據庫
redisDb *db;
// 服務器的數據庫數量
int dbnum;
// ...
}
數據庫鍵空間
Redis是一個鍵值對數據庫服務器,服務器中的每個數據庫都由一個redis.h/redisDb結構表示,其中redisDb結構的dict字典保存了數據庫中的所有鍵值對,我們將這個字典稱為鍵空間(key space):
typedef struct redisDb {
// ..
//數據庫鍵空間,保存着數據庫的所有鍵值對
dict *dict;
// ..
} redisDb;
鍵空間和用詞所見的數據庫是直接對應的:
- 鍵空間的鍵就是數據庫的鍵,每個鍵是一個字符串對象。
- 鍵空間的值就是數據庫的值,每個值可以是字符串對象、列表對象、哈希表對象、集合對象和有序集合對象中的任意一種Redis對象。
鍵的過期時間
通過EXPIRE命令或者PEXPIRE命令,客戶端可以以秒或者毫秒精度為數據庫中的某個鍵設置生存時間(Time To Live,TTL),在經過指定的秒數或者毫秒數之后,服務器就會自動刪除生存時間為0的鍵。
redisDb結構的expires字典保存了數據庫中所有鍵的過期時間,我們稱這個字典為過期字典:
- 過期字典的鍵是一個指針,指向鍵空間中的某個鍵對象。
- 過期字典的值是一個long,表示此鍵的過期時間。
typedef struct redisDb {
// ...
// 過期字典,保存着鍵的過期時間
dict *expires;
// ...
} redisDb;
過期鍵刪除策略
如果一個鍵過期了,那么它什么時候被刪除?
這個問題可能有三種可能的答案,分別代表了三種不同的刪除策略:
Redis服務器實際使用的是惰性刪除和定期刪除兩種策略:通過配合使用這兩種刪除策略,服務器可以很好地在合理使用CPU時間和避免浪費內存空間之間取得平衡。
AOF、RDB和復制功能對過期鍵的處理
RDB對過期鍵的處理
- 生成RDB文件:執行SAVE命令或者BGSAVE命令所產生的新RDB文件不會包含已經過期的鍵。
- 載入RDB文件:如果服務器是主服務器,載入RDB時程序只會雲載入未過期的鍵;如果服務器是從服務器,載入RDB時全部載入,不過當進行數據同步時,從服務器的數據庫就會被清空,所以過期鍵不會造成影響。
AOF對過期鍵的處理
- AOF寫入:當過期鍵被刪除后,程序會向AOF文件追加一條DEL命令。
- AOF重寫:程序會對數據庫中的鍵進行檢查,已過期的鍵不會被保存到重寫后的AOF文件中。
更多關於AOF和RDB的內容,請查看Redis基礎(三)RDB與AOF持久化
復制對過期鍵的處理
當服務器運行在復制模式下時,從服務器的過期鍵刪除運作由主服務器控制:
- 主服務器在刪除一個過期鍵后,會顯式地向所有從服務器發送一個DEL命令,告知從服務器刪除這個過期鍵。-
- 從服務器即使發現過期鍵也不會自作主張地刪除它,而是等待主節點發來DEL命令,這種統一、中心化的過期鍵刪除策略可以保證主從服務器數據的一致性。