資料庫
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命令,這種統一、中心化的過期鍵刪除策略可以保證主從伺服器資料的一致性。