Redis資料結構之壓縮列表ziplist

2021-09-14 05:41:40 字數 1551 閱讀 4784

原始碼版本:redis  5.0.4

ziplist是乙個特殊編碼的雙鏈表,他被設計出來用以節省記憶體,它可以同時儲存字串和整整形數,其中整數被編碼為實際整數,而不是一系列字元。它可以在o(1)的時間進行頭部的插入和尾部的插入,但是他的每次插入都需要進行記憶體的分配,耗時與表中節點數目有關。

ziplist記憶體布局

ziplist總體記憶體布局如下圖所示:

zlbytes:無符號32位整形數,它儲存了整個ziplist的長度,包括他自身的長度,在增加鍊錶長度的時候不需要遍歷整個列表。

zltail:無符號32整形數,它儲存了列表中最後乙個元素的偏移位置,在列表尾端操作時不需要遍歷列表。

zllen:無符號16位短整型數,他儲存了鍊錶的個數,當列表中元素個數超過2^16-2 時,

它的值設為2^16-1,此時只有遍歷整個列表才知道鍊錶中元素的個數。

zlend:無符號8位的整形數,列表的結尾識別符號。

entry:列表中儲存的具體元素。

entry結構詳解

entry的總體記憶體布局如下圖所示:

當元素儲存的是非常小的整數時,資料可以儲存在encode當中此時其記憶體布局如下所示:

prevlen表示列表當中前乙個元素的長度,其所佔記憶體可能為1個位元組也可能為5個位元組,當prev的值為0~253時,它佔乙個位元組的記憶體,當prev第乙個位元組的值為254時,它佔5個位元組的記憶體。

encode欄位決定了儲存資料的型別,其具體表示如下分析:

當encode的前兩個位元位為00時,encode佔乙個位元組,它最大可以儲存63bytes的資料,其長度由6個bit位來儲存(|00pppppp|);

當encode的前兩個位元位為01時,encode佔兩個位元組,它最大可以儲存16383bytes的資料,其長度由14個bit位來儲存(|01pppppp|qqqqqqqq|);

當encode的前兩個位元位為10時,encode佔五個位元組,它儲存超過16383bytes的資料,最多儲存32^2-1bytes的資料,其長度由6個bit位來儲存(|10000000|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt| );

當encode的前兩個位元位為11時,其情況如下:

|11000000|整體佔3個位元組,其儲存 int16_t型別數

|11010000|整體佔5個位元組,其儲存 int32_t型別數

|11100000|整體佔9個位元組,其儲存 int64_t型別數

|11110000|整體佔4個位元組,其儲存 24bit整型數

|11111110|整體佔2個位元組,其儲存 8 bit整型數

|1111***x|整體佔1個位元組,儲存1~13的值

|11111111|特殊的列表元素

Redis 資料結構之 壓縮列表

壓縮列表是一塊連續的記憶體空間,元素之間緊挨著儲存,沒有任何冗餘空隙。struct ziplist entry 塊隨著容納的元素型別不同,也會有不一樣的結構。struct entry encoding 字段儲存了元素內容的編碼型別資訊,ziplist 通過這個欄位來決定後面的 content 內容的...

redis資料結構 壓縮列表

但凡是名稱中有 壓縮 兩個字的,都是為了節約記憶體。壓縮列表也不例外。以下是壓縮列表的結構圖 zlbytes zltail zllen entry1 entry2 entryn zlend 說明 屬性 型別長度 用途zlbytes unit32 t 4bit 記錄整個ziplist占用的記憶體位元組...

Redis資料結構 壓縮列表

同整數集合一樣壓縮列表也不是基礎資料結構,而是 redis 自己設計的一種資料儲存結構。它有點兒類似陣列,通過一片連續的記憶體空間,來儲存資料。不過,它跟陣列不同的一點是,它允許儲存的資料大小不同。聽到 壓縮 兩個字,直觀的反應就是節省記憶體。之所以說這種儲存結構節省記憶體,是相較於陣列的儲存思路而...