Redis基礎(二)數據庫

數據庫

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

參考資料

Tags: