Redis有序集合原理

biggirl發表於2018-05-14

簡介

有序集合是一個資料型別和集合和hash表很相似,資料是不重複的。由於集合中的元素是沒有排序的,因此有序集合中的每個元素都和一個浮點型數字關聯起來,這個浮點型數字叫做score(所以它和hash很像)。
有序集合內的元素是按照以下規則排序的。
① A和B是2個分數不同的元素。如果A的分數大於B的分數,那麼A>B。
② 如果A和B分數相同,那麼當A的字串詞典順序比B的到時候,A>B(A和B的字串不可能相等)。

有序集合實現

Redis有序集合中的元素的編碼可以是 ziplist 或者 skiplist。ziplist和skiplist編碼選擇的標準在於Redis裡的元素的數量以及元素成員的長度。當滿足以下2個條件時,元素編碼為ziplist:
① 有序集合儲存的元素數量小於128個
② 有序集合儲存的所有元素成員的長度小於64位元組

同時當條件不滿足的時候,ziplist可以向skiplist轉換。

以下將具體介紹ziplist和skiplist編碼的底層實現。
ziplist:
ziplist編碼的有序集合物件使用壓縮列表作為底層實現。每個集合使用2個緊挨在一起的壓縮列表節點來儲存,第一個儲存元素的成員,第二個儲存元素的分值。壓縮列表內的集合按分值從小到大排序,分值較小的元素被放置在靠近表頭的位置,分值較大的元素在靠近表尾的位置。

skiplist:
skiplist編碼的有序集合物件使用 zset結構作為底層實現,zset結構同時包含一個字典和一個跳躍表。
zset結構的zsl跳躍表按分值從小到大儲存了所有集合元素,每個跳躍表都儲存了一個集合元素:跳躍表節點的object屬性儲存了元素的成員,而跳躍表節點的score屬性儲存了元素的分值。
從了zsl, zset裡還儲存了一個從成員到分值的對映。

思考

1 為什麼有序集合需要同時使用跳躍表和字典來實現?
跳躍表利於執行範圍操作(跳躍表是排好序的),而字典有利於執行分值查詢操作。同時由於Redis裡的跳躍表和字典元素很多都是用指標實現的,所以不會浪費記憶體。

2 壓縮列表和跳躍表之間的區別?
壓縮列表是Redis為了節約記憶體而開發的。是由一系列特殊編碼的連續記憶體塊組成的順序型儲存結構。當一個列表鍵只包含少量列表項,並且每個列表項要麼是小整數值,要麼是長度比較小的字串,Redis就會用壓縮列表作為其底層實現。
跳躍表是一種有序資料結構。它通過在每個節點中維持多個指向其它節點的指標,從而達到快速訪問節點的目的。

參考文件:
redis官方文件
《redis設計與實現》

相關文章