Redis 數(shù)據(jù)庫

2018-08-02 11:56 更新

數(shù)據(jù)庫

本章將對 Redis 數(shù)據(jù)庫的構(gòu)造和實現(xiàn)進行討論。

除了說明數(shù)據(jù)庫是如何儲存數(shù)據(jù)對象之外,本章還會討論鍵的過期信息是如何保存,而 Redis 又是如何刪除過期鍵的。

數(shù)據(jù)庫的結(jié)構(gòu)

Redis 中的每個數(shù)據(jù)庫,都由一個 redis.h/redisDb 結(jié)構(gòu)表示:

typedef struct redisDb {

    // 保存著數(shù)據(jù)庫以整數(shù)表示的號碼
    int id;

    // 保存著數(shù)據(jù)庫中的所有鍵值對數(shù)據(jù)
    // 這個屬性也被稱為鍵空間(key space)
    dict *dict;

    // 保存著鍵的過期信息
    dict *expires;

    // 實現(xiàn)列表阻塞原語,如 BLPOP
    // 在列表類型一章有詳細的討論
    dict *blocking_keys;
    dict *ready_keys;

    // 用于實現(xiàn) WATCH 命令
    // 在事務(wù)章節(jié)有詳細的討論
    dict *watched_keys;

} redisDb;

下文將詳細討論 id 、 dictexpires 三個屬性,以及針對這三個屬性所執(zhí)行的數(shù)據(jù)庫操作。

數(shù)據(jù)庫的切換

redisDb 結(jié)構(gòu)的 id 域保存著數(shù)據(jù)庫的號碼。

這個號碼很容易讓人將它和切換數(shù)據(jù)庫的 SELECT 命令聯(lián)系在一起,但是,實際上,id 屬性并不是用來實現(xiàn) SELECT 命令,而是給 Redis 內(nèi)部程序使用的。

當 Redis 服務(wù)器初始化時,它會創(chuàng)建出 redis.h/REDIS_DEFAULT_DBNUM 個數(shù)據(jù)庫,并將所有數(shù)據(jù)庫保存到 redis.h/redisServer.db 數(shù)組中,每個數(shù)據(jù)庫的 id 為從 0REDIS_DEFAULT_DBNUM - 1 的值。

當執(zhí)行 SELECT number 命令時,程序直接使用 redisServer.db[number] 來切換數(shù)據(jù)庫。

但是,一些內(nèi)部程序,比如 AOF 程序、復(fù)制程序和 RDB 程序,需要知道當前數(shù)據(jù)庫的號碼,如果沒有 id 域的話,程序就只能在當前使用的數(shù)據(jù)庫的指針,和 redisServer.db 數(shù)組中所有數(shù)據(jù)庫的指針進行對比,以此來弄清楚自己正在使用的是那個數(shù)據(jù)庫。

以下偽代碼描述了這個對比過程:

def PSEUDO_GET_CURRENT_DB_NUMBER(current_db_pointer):
    i = 0
    for db_pointer in redisServer.db:
        if db_pointer == current_db_pointer:
            break
        i += 1
    return i

有了 id 域的話,程序就可以通過讀取 id 域來了解自己正在使用的是哪個數(shù)據(jù)庫,這樣就不用對比指針那么麻煩了。

數(shù)據(jù)庫鍵空間

因為 Redis 是一個鍵值對數(shù)據(jù)庫(key-value pairs database),所以它的數(shù)據(jù)庫本身也是一個字典(俗稱 key space):

redisDb 結(jié)構(gòu)的 dict 屬性中,保存著數(shù)據(jù)庫的所有鍵值對數(shù)據(jù)。

下圖展示了一個包含 numberbook 、 message 三個鍵的數(shù)據(jù)庫 ——其中 number 鍵是一個列表,列表中包含三個整數(shù)值;book 鍵是一個哈希表,表中包含三個鍵值對;而 message 鍵則指向另一個字符串:

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號