1. String 字元串是 Redis 最基本的數據類型,不僅所有 key 都是字元串類型,其它幾種數據類型構成的元素也是字元串。註意字元串的長度不能超過 512M。 1.1 編碼方式(encoding) 字元串對象的編碼可以是 int ,raw 或者 embstr 。 int 編碼:保存的是可以 ...
1. String
字元串是 Redis 最基本的數據類型,不僅所有 key 都是字元串類型,其它幾種數據類型構成的元素也是字元串。註意字元串的長度不能超過 512M。
1.1 編碼方式(encoding)
字元串對象的編碼可以是 int ,raw 或者 embstr 。
- int 編碼:保存的是可以用 long 類型表示的整數值。
- embstr 編碼:保存長度小於 44 位元組的字元串(redis3.2 版本之前是 39 位元組,之後是 44 位元組)。
- raw 編碼:保存長度大於 44 位元組的字元串(redis3.2 版本之前是 39 位元組,之後是 44 位元組)。
<
int 編碼是用來保存整數值,而 embstr 是用來保存短字元串,raw 編碼是用來保存長字元串。
1.2 raw 編碼
*ptr 指向實際 SDS 存儲位置。記憶體不連續
1.3 embstr 編碼
記憶體連續,意味著 redis 在申請記憶體空間時只需要調用一次申請記憶體函數,減少用戶態內核態交換,效率高。
1.4 int 編碼
如果存儲的字元串是整數值,並且大小在 LONG_MAX 範圍內,則會採用 INT 編碼:直接將數據保存在 RedisObject 的 ptr 指針位置(剛好 8 位元組),不再需要 SDS 了。
1.5 總結
2. List
list 列表,它是簡單的字元串列表,按照插入順序排序,你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊),它的底層實際上是個鏈表結構。
2.1 編碼方式(encoding)
列表對象的編碼是 quicklist。 (之前版本中有 linkedList 和 ziplist 這兩種編碼。進一步的,目前 Redis 定義的 10 個對象編碼方式巨集名中,有兩個被完全閑置了,分別是: OBJ_ENCODING_ZIPMAP 與 OBJ_ENCODING_LINKEDLIST。 從 Redis 的演進歷史上來看,前者是後續可能會得到支持的編碼值(代碼還在), 後者則應該是被徹底淘汰了)
2.2 記憶體佈局
3. Set
集合對象 set 是 string 類型(整數也會轉換成 string 類型進行存儲)的無序集合。註意集合和列表的區別:集合中的元素是無序的,因此不能通過索引來操作元素;集合中的元素不能有重覆。
3.1 編碼方式(encoding)
集合對象的編碼可以是 intset 或者 hashtable; 底層實現有兩種,分別是 intset 和 dict 。 顯然當使用 intset 作為底層實現的數據結構時,集合中存儲的只能是數值數據,且必須是整數;而當使用 dict 作為集合對象的底層實現時,是將數據全部存儲於 dict 的鍵中,值欄位閑置不用.
3.2 記憶體佈局
3.3 編碼轉換
當集合同時滿足以下兩個條件時,使用 intset 編碼:
- 集合對象中所有元素都是整數
- 集合對象所有元素數量不超過 512
不能滿足這兩個條件的就使用 hashtable 編碼。第二個條件可以通過配置文件的 set-max-intset-entries 進行配置。
4. Zset
和上面的集合對象相比,有序集合對象是有序的。與列表使用索引下標作為排序依據不同,有序集合為每個元素設置一個分數(score)作為排序依據。
4.1 編碼方式(encoding)
- SkipList & HT(Dict):SkipList 可以排序,並且可以同時存儲 score 和 ele 值(member);HT 可以鍵值存儲,並且可以根據 key 找 value
- ZipList :當 節點 entry 數量 小於 128 並且 每個節點大小小於 64kb 時採用
4.2 記憶體結構
SkipList & HT(Dict)
ZipList
當元素數量不多時,HT 和 SkipList 的優勢不明顯,而且更耗記憶體。因此 zset 還會採用 ZipList 結構來節省記憶體,不過需要同時滿足兩個條件:
- 元素數量小於 zset_max_ziplist_entries,預設值 128
- 每個元素都小於 zset_max_ziplist_value 位元組,預設值 64
ziplist 本身沒有排序功能,而且沒有鍵值對的概念,因此需要有 zset 通過編碼實現:
- ZipList 是連續記憶體,因此 score 和 element 是緊挨在一起的兩個 entry, element 在前,score 在後
- score 越小越接近隊首,score 越大越接近隊尾,按照 score 值升序排列
5. Hash
哈希對象的鍵是一個字元串類型,值是一個鍵值對集合。
5.1 編碼方式(encoding)
哈希對象的編碼可以是 ziplist 或者 hashtable;對應的底層實現有兩種,一種是 ziplist, 一種是 dict。
5.2 記憶體佈局
Hash 結構與 Redis 中的 Zset 非常類似:
- 都是鍵值存儲
- 都需求根據鍵獲取值
- 鍵必須唯一
區別如下:
- zset 的鍵是 member,值是 score;hash 的鍵和值都是任意值
- zset 要根據 score 排序;hash 則無需排序
當 Hash 中數據項比較少的情況下,Hash 底層才⽤壓縮列表 ziplist 進⾏存儲數據,隨著數據的增加,底層的 ziplist 就可能會轉成 dict,具體配置如下:
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
本文由
傳智教育博學谷
教研團隊發佈。如果本文對您有幫助,歡迎
關註
和點贊
;如果您有任何建議也可留言評論
或私信
,您的支持是我堅持創作的動力。轉載請註明出處!