[redis] 數據類型 -- 快速列表

說明

版本 < 3.2 時,使用 linkedlist 和 ziplist,也就是元素少時用 ziplist,元素多時用 linkedlist。
版本 ≥ 3.2時,使用 quicklist。
廣泛用於實現 Redis 的各種功能,列表鍵、發佈與訂閱、慢查詢、監視器等
可以通過 debug object xxx(鍵),中的 encoding 查看使用了什麼結構

  1. ziplist 對空間的利用率非常高,在數據規模比較小時,耗時相對可接受,但是對於元素比較多或者是單個元素比較長時,插入、彈出的耗時非常大。
  2. linkedlist 在插入、刪除元素時,元素數量、單個元素的長度對耗時影響小(耗時分佈比較集中),但是空間利用率比較差,特別是數據規模較小時,空間利用率非常差。
  3. quicklist 結合了二者的優點,首先時間消耗上,數據規模對其影響小,其次是空間利用率,因爲底層使用了ziplist,所以在小規模數據上空間表現也良好。

Redis 對象頭結構體

struct RedisObject {
    int4 type; // 4bits
    int4 encoding; // 4bits
    int24 lru; // 24bits
    int32 refcount; // 4bytes
    void *ptr; // 8bytes,64-bit system
} robj;

quicklist 快速列表

  1. 說明: 綜合了 linkedlist 和 ziplist 的特點,同時具有節省內存、插入刪除數據高效的特點
  2. 結構
typedef struct quicklistNode {
    struct quicklistNode *prev;  // 前置節點
    struct quicklistNode *next;  // 後置節點
    unsigned char *zl;					 // 指向壓縮列表
    unsigned int sz;                         // ziplist 的字節總數
    unsigned int count : 16;         // ziplist 中的元素數量
    unsigned int encoding : 2;    // 原生字節數組還是 LZF 壓縮存儲 RAW==1 or LZF==2 */
    unsigned int container : 2;  /* NONE==1 or ZIPLIST==2 */
    unsigned int recompress : 1; /* was this node previous compressed? */
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;
typedef struct quicklist {
    quicklistNode *head;   // 頭節點
    quicklistNode *tail;      // 尾節點
    unsigned long count;  // 元素總數      /* total count of all entries in all ziplists */
    unsigned long len;        // 節點的個數   /* number of quicklistNodes */
    int fill : 16;                         // 正數爲,單個節點允許的最大數量,負數代表單個節點的內存空間大小 -1:4Kb,-2:8kb...   /* fill factor for individual nodes */
    unsigned int compress : 16; //  壓縮深度 0 不壓縮 /* depth of end nodes not to compress;0=off */
} quicklist;
  1. 內部默認單個 ziplist 長度爲 8k 字節,超出了這個字節數,就會新起一個 ziplist。ziplist 的長度由配置參數 list-max-ziplist-size 決定。
  2. compress 實際深度由配置參數 list-compress-depth 決定。爲了支持快速的 push/pop 操作,quicklist 的首尾兩個 ziplist 不壓縮,此時深度就是 1。如果深度爲 2,就表示 quicklist 的首尾第一個 ziplist 以及首尾第二個 ziplist 都不壓縮。
發佈了53 篇原創文章 · 獲贊 9 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章