Redis?哈希Hash底層數(shù)據(jù)結(jié)構(gòu)詳解
1. Redis 底層數(shù)據(jù)結(jié)構(gòu)
Redis數(shù)據(jù)庫就像是一個哈希表,首先對key進行哈希運算得到哈希值再取模得到一個下標(biāo),每個元素是一個節(jié)點,節(jié)點之間形成鏈表。這感覺有點像Java中的HashMap。

不同的數(shù)據(jù)類型的實現(xiàn)方式是不一樣的,可以通過object encoding命令查看底層真正的數(shù)據(jù)存儲結(jié)構(gòu)

同一種類型在不同的條件下所采用的數(shù)據(jù)結(jié)構(gòu)也不一樣,例如:

Redis是鍵值對形式的數(shù)據(jù)庫,key可以是任意值(PS:最終都會轉(zhuǎn)成string),value有多種數(shù)據(jù)類型
詳見:https://redis.io/docs/manual/data-types/data-types-tutorial/

至此,已經(jīng)很清楚,hash底層的結(jié)構(gòu)是 ziplist 和 hashtable
那么,什么時候會從ziplist轉(zhuǎn)成hashtable呢?這個在redis.conf中有相關(guān)的配置,如下:

默認情況下:
當(dāng)ziplist中entry的數(shù)量超過512的時候,會轉(zhuǎn)成hashtable 單個元素的值超過64字節(jié)的時候,會轉(zhuǎn)成hashtable
2. hashtable
在Redis中hashtable就是字典dict
通過源碼,可以看到dict是這樣定義的:


3. redisDb 與 redisObject
通過源碼得知,redisDb代表redis數(shù)據(jù)庫,redisObject代表存到數(shù)據(jù)庫中的數(shù)據(jù)


字典dict的結(jié)構(gòu)前面已經(jīng)看過了,于是整個數(shù)據(jù)庫的結(jié)構(gòu)大概就是下面這個樣子:

4. ziplist

ziplist是一種特殊編碼的雙鏈表,被設(shè)計成非常節(jié)省內(nèi)存。它存儲字符串和整型值,其中整數(shù)被編碼為實際整數(shù),而不是一系列字符。它允許在O(1)時間內(nèi)在列表的任意一邊進行push和pop操作。但是,由于每個操作都需要重新分配ziplist所使用的內(nèi)存,因此實際的復(fù)雜性與ziplist所使用的內(nèi)存量有關(guān)。
ziplist的大體布局如下:
<zlbytes> <zltail> <zllen> <entry> <entry> ... <entry> <zlend>
<uint32_t zlbytes>: 一個無符號整數(shù),用于保存ziplist占用的字節(jié)數(shù),包括zlbytes字段本身的四個字節(jié)。需要存儲這個值,以便能夠調(diào)整整個結(jié)構(gòu)的大小,而不需要首先遍歷它。
<uint32_t zltail> : 列表中最后一個條目的偏移量。
<uint16_t zllen> : 條目的數(shù)量。當(dāng)有超過2^16-2個條目時,這個值被設(shè)置為2^16-1,我們需要遍歷整個列表來知道它包含多少項。
<uint8_t zlend> : 一個特殊的條目,表示 ziplist 的結(jié)尾

5. linkedlist


linkedlist是一個雙向鏈表

6. quicklist



quicklistNode是一個32字節(jié)的結(jié)構(gòu)體,描述快表的ziplist。
quicklist = linkedlist + ziplist

到此這篇關(guān)于Redis 哈希Hash底層數(shù)據(jù)結(jié)構(gòu)詳解的文章就介紹到這了,更多相關(guān)Redis哈希底層數(shù)據(jù)結(jié)構(gòu)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

