天天看點

【redis學習筆記-01-基礎篇】-04-壓縮清單與快速清單

為什麼要将壓縮清單和快速清單放在一起?

什麼是壓縮清單,什麼是快速清單?

要回答上面兩個問題,在此之前我們先了解下redis的清單。

在之前的部落格中有寫到redis的5中基本資料類型,其中就包括 list ,也說過 list 本質上是個雙向連結清單。我們可以把 list 做隊列使用,也可以用 list 來做棧使用。具體應用操作可回顧之前文章。

【redis學習筆記-01-基礎篇】-04-壓縮清單與快速清單

redis出于空間使用率考慮,list 的雙向連結清單結構分為壓縮清單 和 快速清單。在資料量較少的時候會配置設定一塊連續的存儲用作壓縮清單。當資料量較大時,redis會将存儲結構改為快速清單。

list 結構中head 指向連結清單第一個節點,tail指向連結清單最後一個節點, len儲存有連結清單的長度。這樣在擷取連結清單表頭和表尾節點的時間複雜度為O(1)。 

壓縮清單是記憶體上的一整塊連續空間,其中包含了任意多個儲存位元組數組或者整數值的節點組成的資料結構。

【redis學習筆記-01-基礎篇】-04-壓縮清單與快速清單

上方所示為壓縮清單的資料結構,其中

zlbtyes 為整個壓縮清單占用的記憶體位元組數;

zltail 為尾節點距離清單起始位址的偏移量,友善定位尾節點;

zllen 為節點 entry 的個數;

entry 為各節點;

zlend 為清單結尾标志。

entry 結構如下組成

【redis學習筆記-01-基礎篇】-04-壓縮清單與快速清單

prev_len 為目前 entry 節點的上一個節點的長度。因為記錄了前一個節點的長度,是以可以通過節點的位址偏移量來計算出上一個節點的位址位置。整個屬性是實作壓縮清單從列尾向前周遊的關鍵。

content 儲存了節點的值,content 儲存的可以是一個位元組數組,也可以是整數。

encoding 屬性是對content的描述,可以記錄content的長度,類型,甚至當節點值是小整數時,encoding 通過自身編碼結構可以記錄這個節點值。

快速清單是雙向連結清單和壓縮清單的結合,即雙向連結清單的每一個節點其實是一個壓縮清單。

因為純的雙向連結清單 prev 和 next指針占用一些位元組空間,且大量的節點造成 prev 和 next 占用空間膨脹,且每個節點單獨配置設定造成空間碎片增加。後面redis在新的版本中采用了壓縮清單和雙向清單結合的方式來改造清單的存儲。其結構大緻如下圖所示:

【redis學習筆記-01-基礎篇】-04-壓縮清單與快速清單

快速清單節點的壓縮清單預設長度為8KB,可通過list-max-ziplist-size參數配置,當超過這個位元組數時,就會另起一個壓縮清單。