1. 程式人生 > >Redis數據結構之壓縮列表

Redis數據結構之壓縮列表

哈希 組成 數據 rev nts 以及 復雜 技術 con

  壓縮列表是Redis為了節約內存而開發的,由一系列特殊編碼的連續內存塊組成的順序型數據結構。一個壓縮列表可以包含任意多個節點,每個節點可以保存一個字節數組或者一個整數值。

一、壓縮列表結構
1. 壓縮列表結構:

技術分享圖片

參數說明:
zlbytes:記錄整個壓縮列表占用的內存字節數。
zltail:記錄壓縮列表表尾節點距離壓縮列表起始地址有多少字節。
zllen:記錄了壓縮列表包含的節點數量。
entryN:壓縮列表的節點,節點長度由節點保存的內容決定。
zlend:特殊值0xFF(十進制255),用於標記壓縮列表的末端。
2. 壓縮列表節點結構:

技術分享圖片

參數說明:
previous_entry_length:記錄壓縮列表中前一個節點的長度。previous_entry_length屬性的長度可以是1字節或者5字節:如果前一節點的長度小於 254 字節,那麽previous_entry_length屬性的長度為1字節,前一節點的長度就保存在這一個字節裏面。如果前一節點的長度大於等於254字節,那麽previous_entry_length屬性的長度為5字節,其中屬性的第一字節會被設置為0xFE(十進制值 254),而之後的四個字節則用於保存前一節點的長度。因為節點的previous_entry_length屬性記錄了前一個節點的長度,所以程序可以通過指針運算,根據當前節點的起始地址來計算出前一個節點的起始地址,縮列表的從表尾向表頭遍歷操作就是使用這一原理實現的。


encoding:記錄節點的contents屬性所保存數據的類型以及長度。分兩種情況:(1)一字節、兩字節或者五字節長,值的最高位為00 、01或者10的是字節數組編碼,這種編碼表示節點的content屬性保存著字節數組,數組的長度由編碼除去最高兩位之後的其他位記錄;(2)一字節長,值的最高位以11開頭的是整數編碼,這種編碼表示節點的content屬性保存著整數值,整數值的類型和長度由編碼除去最高兩位之後的其他位記錄。
contents:保存節點的值,可以是一個字節數組或整數,類型和長度由節點的‘encoding‘屬性決定。

二、連鎖更新
  由於壓縮列表的‘previous_entry_length‘屬性可能是1字節或5字節,若在一個壓縮列表中,有多個連續的、長度介於250字節到253字節之間的節點,則添加新節點或刪除節點都有可能會引發多個節點的連續多次空間擴展,這種現象稱之為“連鎖更新”。


因為連鎖更新在最壞情況下需要對壓縮列表執行N次空間重分配操作, 而每次空間重分配的最壞復雜度為O(N), 所以連鎖更新的最壞復雜度為O(N^2)。但“連鎖更新”發生的概率是很低的,所以不必擔心其會影響壓縮列表的性能。

三、壓縮列表在Redis中的用途
1. 作為列表鍵的底層實現之一:當一個列表鍵只包含少量列表項,並且每個列表項要麽就是小整數值,要麽就是長度比較短的字符串,那麽Redis就會使用壓縮列表來做列表鍵的底層實現。
2. 作為哈希鍵的底層實現之一:當一個哈希鍵只包含少量鍵值對,並且每個鍵值對的鍵和值要麽就是小整數值,要麽就是長度比較短的字符串,那麽Redis就會使用壓縮列表來做哈希鍵的底層實現。

Redis數據結構之壓縮列表