目錄
- 1、背景
- 2、壓縮列表
- 【1】底層結構
- 【2】特性
- 【3】優缺點
1、背景
ziplist(壓縮列表)是redis中一種特殊編碼的雙向鏈表數據結構,主要用于存儲小型列表和哈希表。它通過緊湊的內存布局和特殊的編碼方式來節省內存空間。
2、壓縮列表
【1】底層結構
ziplist并不是一個顯式的c結構體,而是通過緊湊的字節數組來實現的。它沒有傳統的struct定義,而是通過內存布局和偏移量來管理數據,其結構如下:
//ziplist整體結構
<zlbytes> <zltail> <zllen> <entry> <entry> ... <entry> <zlend>
字段含義如下:
字段 | 大小(字節) | 說明 |
---|---|---|
zlbytes | 4 | 整個ziplist占用的內存字節數(uint32_t) |
zltail | 4 | 最后一個entry的偏移量(uint32_t) |
zllen | 2 | entry的數量(uint16_t),如果超過2^16-1,需要遍歷整個ziplist才能獲取準確數量 |
entry | 變長 | 存儲的實際數據項 |
zlend | 1 | 固定值0xFF,表示ziplist結束 |
每個entry的存儲方式如下:
<prevlen> <encoding> <entry-data>
字段含義如下:
字段 | 大小 | 說明 |
---|---|---|
prevlen | 1或5字節 | 前一個entry的長度(用于方向遍歷) |
encoding | 1、2或5字節 | 當前entry的數據類型和長度 |
entry-data | 變長 | 實際存儲的數據 |
可以看到encoding和entry-data的長度是可變的,prevlen的編碼規則如下:
1、如果前一個entry的長度 < 254字節,則prevlen占用1字節(直接存儲長度值)。
2、如果前一個entry的長度 >= 254字節,則prevlen占用5字節(第一個字節是0xFE,后4字節存儲實際長度)。
encoding的編碼規則如下:
1、如果數據類型為整數,就使用1字節編碼。
2、如果數據類型為字符串,就根據字符串長度大小使用1、2、5字節編碼。
【2】特性
ziplist的特性如下:
特性 | 描述 |
---|---|
內存緊湊 | 通過特殊編碼減少內存使用 |
雙向遍歷 | 支持從前往后和從后往前遍歷 |
變長編碼 | 根據數據大小使用不同長度的編碼 |
自動升級 | 當數據超過閾值時會自動轉換為其它結構 |
連續內存 | 所有數據存儲在連續內存塊中 |
無指針 | 使用偏移量而非指針,節省空間 |
【3】優缺點
ziplist的優缺點如下:
優點 | 缺點 |
---|---|
內存效率高,節省空間 | 插入/刪除操作可能導致連鎖更新 |
緩存局部性好 | 查找效率O(n),不適合大數據量 |
減少內存碎片 | 修改操作可能需要重新分配內存 |
適合小數據量存儲 | 編碼/解碼需要額外CPU開銷 |
自動轉換機制 | 最大長度有限制(默認64KB) |