博客 / 詳情

返回

這次我把 Redis 數據類型寫出了花✿❀🎉~~~

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 字節)。

<file

int 編碼是用來保存整數值,而 embstr 是用來保存短字符串,raw 編碼是用來保存長字符串。

1.2 raw 編碼

file
*ptr 指向實際 SDS 存儲位置。內存不連續

1.3 embstr 編碼

file

內存連續,意味着 redis 在申請內存空間時只需要調用一次申請內存函數,減少用户態內核態交換,效率高。

1.4 int 編碼

如果存儲的字符串是整數值,並且大小在 LONG_MAX 範圍內,則會採用 INT 編碼:直接將數據保存在 RedisObject 的 ptr 指針位置(剛好 8 字節),不再需要 SDS 了。

1.5 總結

file

2. List

list 列表,它是簡單的字符串列表,按照插入順序排序,你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊),它的底層實際上是個鏈表結構。

2.1 編碼方式(encoding)

列表對象的編碼是 quicklist。 (之前版本中有 linkedList 和 ziplist 這兩種編碼。進一步的,目前 Redis 定義的 10 個對象編碼方式宏名中,有兩個被完全閒置了,分別是: OBJ_ENCODING_ZIPMAP 與 OBJ_ENCODING_LINKEDLIST。 從 Redis 的演進歷史上來看,前者是後續可能會得到支持的編碼值(代碼還在), 後者則應該是被徹底淘汰了)

2.2 內存佈局

file

3. Set

集合對象 set 是 string 類型(整數也會轉換成 string 類型進行存儲)的無序集合。注意集合和列表的區別:集合中的元素是無序的,因此不能通過索引來操作元素;集合中的元素不能有重複。

3.1 編碼方式(encoding)

集合對象的編碼可以是 intset 或者 hashtable; 底層實現有兩種,分別是 intset 和 dict 。 顯然當使用 intset 作為底層實現的數據結構時,集合中存儲的只能是數值數據,且必須是整數;而當使用 dict 作為集合對象的底層實現時,是將數據全部存儲於 dict 的鍵中,值字段閒置不用.

3.2 內存佈局

file

3.3 編碼轉換

當集合同時滿足以下兩個條件時,使用 intset 編碼:

  1. 集合對象中所有元素都是整數
  2. 集合對象所有元素數量不超過 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)
file

ZipList

file

當元素數量不多時,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 內存佈局

file
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

本文由傳智教育博學谷教研團隊發佈。

如果本文對您有幫助,歡迎關注點贊;如果您有任何建議也可留言評論私信,您的支持是我堅持創作的動力。

轉載請註明出處!

user avatar FatTiger4399 頭像 codingdgsun 頭像 docker_app 頭像 13917911249 頭像
4 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.