1. 程式人生 > 實用技巧 >Redis 列表物件

Redis 列表物件

列表物件的編碼可以是ziplist或者linkedlist

ziplist編碼的列表物件使用壓縮列表作為底層實現, 每個壓縮列表節點(entry)儲存了一個列表元素。

舉個例子, 如果我們執行以下RPUSH命令, 那麼伺服器將建立一個列表物件作為numbers鍵的值:

redis> RPUSH numbers 1 "three" 5
(integer) 3

如果numbers鍵的值物件使用的是ziplist編碼, 這個這個值物件將會是圖 8-5 所展示的樣子。

另一方面,linkedlist編碼的列表物件使用雙端連結串列作為底層實現每個雙端連結串列節點(node)都儲存了一個字串物件, 而每個字串物件都儲存了一個列表元素。

舉個例子, 如果前面所說的numbers鍵建立的列表物件使用的不是ziplist編碼, 而是linkedlist編碼, 那麼numbers鍵的值物件將是圖 8-6 所示的樣子。

注意,linkedlist編碼的列表物件在底層的雙端連結串列結構中包含了多個字串物件, 這種巢狀字串物件的行為在稍後介紹的雜湊物件、集合物件和有序集合物件中都會出現, 字串物件是 Redis 五種型別的物件中唯一一種會被其他四種類型物件巢狀的物件。

注意

為了簡化字串物件的表示, 我們在圖 8-6 使用了一個帶有StringObject字樣的格子來表示一個字串物件, 而StringObject字樣下面的是字串物件所儲存的值。

比如說, 圖 8-7 代表的就是一個包含了字串值"three"的字串物件, 它是 8-8 的簡化表示。

編碼轉換

當列表物件可以同時滿足以下兩個條件時, 列表物件使用ziplist編碼:

  1. 列表物件儲存的所有字串元素的長度都小於64位元組
  2. 列表物件儲存的元素數量小於512

不能滿足這兩個條件的列表物件需要使用linkedlist編碼

注意

以上兩個條件的上限值是可以修改的, 具體請看配置檔案中關於list-max-ziplist-value選項和list-max-ziplist-entries選項的說明。

對於使用ziplist編碼的列表物件來說, 當使用ziplist編碼所需的兩個條件的任意一個不能被滿足時, 物件的編碼轉換操作就會被執行: 原本儲存在壓縮列表裡的所有列表元素都會被轉移並儲存到雙端連結串列裡面, 物件的編碼也會從ziplist

變為linkedlist

以下程式碼展示了列表物件因為儲存了長度太大的元素而進行編碼轉換的情況:

# 所有元素的長度都小於 64 位元組
redis> RPUSH blah "hello" "world" "again"
(integer) 3

redis> OBJECT ENCODING blah
"ziplist"

# 將一個 65 位元組長的元素推入列表物件中
redis> RPUSH blah "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"
(integer) 4

# 編碼已改變
redis> OBJECT ENCODING blah
"linkedlist"

除此之外, 以下程式碼展示了列表物件因為儲存的元素數量過多而進行編碼轉換的情況:

# 列表物件包含 512 個元素
redis> EVAL "for i=1,512 do redis.call('RPUSH', KEYS[1], i) end" 1 "integers"
(nil)

redis> LLEN integers
(integer) 512

redis> OBJECT ENCODING integers
"ziplist"

# 再向列表物件推入一個新元素,使得物件儲存的元素數量達到 513 個
redis> RPUSH integers 513
(integer) 513

# 編碼已改變
redis> OBJECT ENCODING integers
"linkedlist"