Redis原始碼分析 ziplist壓縮列表

2021-10-25 12:50:57 字數 1988 閱讀 4192

redis中的list是乙個有序(按加入的時序排序)的資料結構,一般有序我們會採用陣列或者是雙向鍊錶,其中雙向鍊錶由於有前後指標實際上會很浪費記憶體。3.2版本之前採用兩種資料結構作為底層實現:

ziplist的資料結構及解釋如下:

[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-3sqbo573-1610531492142)(

ziplist的節點資訊如下:

typedef

struct zlentry zlentry;

返回乙個zlenrty

static zlentry zipentry

(unsigned

char

*p)

ziplist是使用連續的記憶體塊儲存的:

注意zllen用16個位元位儲存,也就是說起長度最大表示65535,所以如果長度超過這個值,只能夠通過節點遍歷來確定列表元素數量

每個節點zlentry是如何儲存的,完整的zlentry由以下幾個部分組成:

unsigned int lensize, len: lensize表示編碼 len 所需的位元組大小,len表示當前節點值的長度

unsigned int headersize: 當前節點 header 的大小,等於 prevrawlensize + lensize

unsigned char encoding: 當前節點值所使用的編碼型別

ziplist資料結構中prevrawlen是變長編碼的,如果上乙個節點長度小於254個位元組,則只是用乙個位元組儲存prevrawlen,如果大於等於254,那麼第乙個位元組用254標記,後面四個位元組表示上乙個節點長度

ziplist 最大的確定就是連鎖更新問題

因為在ziplist中,每個zlentry都儲存著前乙個節點所佔的位元組數,而這個數值又是變長編碼的。假設存在乙個壓縮列表,其包含 e1、e2、e3、e4…,e1 節點的大小為 253 位元組,那麼 e2.prevrawlen 的大小為 1 位元組,如果此時在 e2 與 e1 之間插入了乙個新節點 e,e 編碼後的整體長度(包含 e1 的長度)為 254 位元組,此時 e2.prevrawlen 就需要擴充為 5 位元組;如果 e2 的整體長度變化又引起了 e3.prevrawlen 的儲存長度變化,那麼 e3 也需要擴…如此遞迴直到表尾節點或者某乙個節點的 prevrawlen 本身長度可以容納前乙個節點的變化。其中每一次擴充都需要進行空間再分配操作。刪除節點亦是如此,只要引起了操作節點之後的節點的 prevrawlen 的變化,都可能引起連鎖更新,引發記憶體 realloc。

連鎖更新在最壞情況下需要進行 n 次空間再分配,而每次空間再分配的最壞時間複雜度為 o(n),因此連鎖更新的總體時間複雜度是 o(n^2)。

基於上述來看ziplist的缺點大於優點,所以3.2版本之後採用了另外乙個資料結構為quicklist

redis> rpush lst 1 3 5 10086 "hello"

"world"

(integer)6

redis> object encoding lst

"ziplist"

redis> hmset profile "name"

"jack"

"age" 28 "job"

"programmer"

ok

redis> object encoding profile

"ziplist"

雜湊鍵裡面包含的所有鍵和值都是小整數值或者短字串

ps: 以上截圖來自《redis設計與實現一書》

Redis原始碼分析 intset h c

intset.h c 是redis 的整數set實現,intset的結構體如下 基本結構 typedef struct intset intset intset的第乙個成員encoding,表明contents中的儲存資料的資料長度,可以是16bits,32bits,64bits。第二個成員leng...

Redis原始碼分析系列

redis目前熱門nosql記憶體資料庫,量不是很大,本系列是本人閱讀redis原始碼時記錄的筆記,由於時間倉促和水平有限,文中難免會有錯誤之處,歡迎讀者指出,共同學習進步,本文使用的redis版本是2.8.19。redis之hash資料結構 redis之intset資料結構 redis之skipl...

redis原始碼分析 adlist

typedef struct listnode listnode 首先定義了乙個節點,包含前驅和後繼以及對應的value typedef struct listiter listiter list的迭代器,next指標和迭代方向 typedef struct list list 鍊錶內容 head和...