1. 程式人生 > 其它 >Redis - ZSet底層資料結構

Redis - ZSet底層資料結構

zset底層的儲存結構包括ziplist或skiplist,在同時滿足一下兩個條件的時候使用ziplist,其他時候使用skiplist,兩個條件如下:

  • 有序集合儲存的袁術數量小於128個
  • 有序集合儲存的所有元素的長度小於64位元組
  • 其他:
    不能滿足上面兩個條件的使用 skiplist 編碼。以上兩個條件也可以通過Redis配置檔案zset-max-ziplist-entries 選項和 zset-max-ziplist-value 進行修改
    對於一個 REDIS_ENCODING_ZIPLIST 編碼的 Zset, 只要滿足以上任一條件, 則會被轉換為 REDIS_ENCODING_SKIPLIST 編碼

 

當ziplist作為zset的底層儲存結構時,每個集合元素使用兩個緊挨在一起的壓縮列表結點來儲存,第一個結點儲存元素的成員,第二個結點儲存元素的分值。

當skiplist作為zset的底層儲存結構的時候,使用skiplist按序儲存元素及分值,使用dict來儲存元素和分值的對映關係。

ziplist資料結構

ziplist 編碼的 Zset 使用緊挨在一起的壓縮列表節點來儲存,第一個節點儲存 member,第二個儲存 score。ziplist 內的集合元素按 score 從小到大排序,其實質是一個雙向連結串列。雖然元素是按 score 有序排序的, 但對 ziplist 的節點指標只能線性地移動,所以在 REDIS_ENCODING_ZIPLIST 編碼的 Zset 中, 查詢某個給定元素的複雜度為 O(N)。

 

 

緊挨著的時元素member個分值score,整體資料是有序格式。

 

skiplist資料結構

skiplist 編碼的 Zset 底層為一個被稱為 zset 的結構體,這個結構體中包含一個字典和一個跳躍表。跳躍表按 score 從小到大儲存所有集合元素,查詢時間複雜度為平均 O(logN),最壞 O(N) 。字典則儲存著從 member 到 score 的對映,這樣就可以用 O(1)的複雜度來查詢 member 對應的 score 值。雖然同時使用兩種結構,但它們會通過指標來共享相同元素的 member 和 score,因此不會浪費額外的記憶體。

 

 

核心點主要包括一個dict物件和一個skiplist物件。dict儲存key/value,key為元素,value為分值;skiplist儲存的有序的元素列表,每個元素包括元素和分值。兩種資料結構下的元素指向相同的位置。