1. 概述
考慮到鏈表的附加空間相對太高,prev 和 next 指針就要占去 16 個字節 (64bit 系統的指針是 8 個字節),另外每個節點的內存都是單獨分配,會加劇內存的碎片化,影響內存管理效率。
后續版本對列表數據結構進行了改造,使用 quicklist 代替了 ziplist 和 linkedlist.
2. 基本結構
quickList 是 zipList 和 linkedList 的混合體,它將 linkedList 按段切分,每一段使用 zipList 來緊湊存儲,多個 zipList 之間使用雙向指針串接起來。

// 快速列表 struct quicklist { quicklistNode* head; quicklistNode* tail; long count; // 元素總數 int nodes; // ziplist 節點的個數 int compressDepth; // LZF 算法壓縮深度 ... } // 快速列表節點 struct quicklistNode { quicklistNode* prev; quicklistNode* next; ziplist* zl; // 指向壓縮列表 int32 size; // ziplist 的字節總數 int16 count; // ziplist 中的元素數量 int2 encoding; // 存儲形式 2bit,原生字節數組還是 LZF 壓縮存儲 ... } struct ziplist_compressed { int32 size; byte[] compressed_data; } struct ziplist { ... }
上述代碼簡單地表示了 quicklist 的大致結構。為了進一步節約空間,Redis 還會對 ziplist 進行壓縮存儲,使用 LZF 算法壓縮,可以選擇壓縮深度。
3.壓縮深度
quicklist 默認的壓縮深度是 0,也就是不壓縮。壓縮的實際深度由配置參數list-compress-depth決定。
為了支持快速的 push/pop 操作,quicklist 的首尾兩個 ziplist 不壓縮,此時深度就是 1。
如果深度為 2,就表示 quicklist 的首尾第一個 ziplist 以及首尾第二個 ziplist 都不壓縮。
4. zipList 長度
quicklist 內部默認單個 ziplist 長度為 8k 字節,超出了這個字節數,就會新起一個 ziplist。
ziplist 的長度由配置參數 list-max-ziplist-size 決定。
