最近在讀黃健宏的《Redis設計與實現》,看完了第一部分,它是採用的自底向上的介紹方法。從最底層的資料結構開始,逐個介紹所用到的資料結構,最後形成資料庫。我準備做個redis的學習筆記,這裡我就自頂向下整理一下。 伺服器中的資料庫
redis伺服器將所有資料庫儲存在伺服器狀態redis.h/redisServer結構的db數組中,db數組中的每項都是一個redis.h/redisDb的結構體,每個redisDb結構就代表一個資料庫。
struct redisServer{ ... // 一個儲存著redisDb的數組,db中的每一項就是一個資料庫 redisDb *db; ...}
redis是一個索引值對資料庫,每個資料庫由一個redisDb結構表示,其中redisDb結構中的字典dict儲存了資料庫中所有的索引值對。
redisDB結構體的定義
typedef struct redisDb{ ... //儲存資料庫中所有的索引值對 dict *dict; ...}
當我們在用戶端輸入
redis>SET msg "hello"OK
時(一般預設是在資料庫0中進行,可以通過SELECT切換資料庫),其實是建立了兩個對象,一個是鍵字串對象(因為鍵總是字串對象),另一個是值字串對象(在這裡是字串對象)。 Redis中的對象
在Redis中,是使用對象來表示資料庫中的鍵和值,鍵總是字串對象,而值的對象可以是字串對象,列表對象,雜湊對象,集合對象,有序集合對象5種。每個對象由一個redisObject結構表示,該結構中和儲存資料有關的三個屬性是type,encoding,ptr。
typedef struct redisObject{ unsigned type ; unsigned encoding; void *ptr; ...}
類型type表示是上述5中對象中的哪一種,再次強調,鍵只能是字串對象(REDIS_STRING)。ptr指標指向對象實現的底層資料結構,encoding表示編碼,不同的編碼所對應的對象實現的資料結構不同。這些底層資料結構有int, embstr, 簡單的動態字串(SDS), 字典, 雙端鏈表,壓縮列表,整數集合,跳躍表,字典等。 資料庫儲存方式
如前所述,Redis的每一個資料庫是由一個redisDb結構表示的,redisDb結構中的dict儲存了資料庫中所有的索引值對,每一個鍵是一個對象,值也是一個對象。一般將這個字典叫做鍵空間。
假如建立了一個字串:
redis>SET message "hello world"
一個列表:
redis>RPUSH alphabet "a" "b" "c"
和一個雜湊表:
redis>HMSET book name "Redis in ACtion" author "Josiah L. Carlson" publisher "Manning"
那麼資料庫的redisDb的儲存方式是如下圖所示的:
注意dict中每個鍵都是一個StringObject, 鍵所對應的值的對象隨著儲存資料的不同而不同。
book這個雜湊表的’name “Redis in ACtion” author “Josiah L. Carlson” publisher “Manning” ’在redisDb中是值,它自己又是個雜湊的對象。它可以通過ziplist(壓縮列表)來實現,又可以通過字典來實現。相當於“大字典”(鍵空間)中套“小字典”(雜湊對象的字典實現)
對於字典的結構,SDS 的結構,壓縮列表的結構,集合或者有序集合的結構將在後面整理。