Redis Zset有序集合實現原理

概要:Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重複的成員。不同的是每個元素都會關聯一個double類型的分數。redis正是通過分數來爲集合中的成員進行從小到大的排序。有序集合的成員是唯一的,但分數(score)卻可以重複。

一、Redis編碼簡介
Redis對象的底層實現數據結構由對象的encoding屬性決定,該屬性記錄了對象的編碼,即對象使用的底層實現的數據結構。這些編碼可以是:

編碼格式 底層數據結構
REDIS_ENCODING_INT long類型的整數
REDIS_ENCODING_ EMBSTR embstr編碼的簡單動態字符串
REDIS_ENCODING_RAW 簡單動態字符串
REDIS_ENCODING_HT 字典
REDIS_ENCODING_LINKEDLIST 雙端鏈表
REDIS_ENCODING_ZIPLIST 壓縮列表
REDIS_ENCODING_INTSET 整數集合
REDIS_ENCODING_SKIPLIST 跳躍表和字典

二、有序集合的編碼可以是ziplist或者skiplist

  • ziplist編碼
    ziplist編碼的有序集合對象使用壓縮列表作爲底層實現,每個集合元素使用兩個緊挨在一起的壓縮列表節點來保存,第一個節點保存元素的成員,第二個元素保存元素的分值。
    壓縮列表內的集合元素按分值從小到大排序。

    zlbyteszltailzllen"apple"5.0"pen"6.0zlend
    屬性 說明
    zlbytes 記錄整個壓縮列表佔用的內存字節數;在對壓縮列表進行內存重分配, 計算 zlend 的位置時使用。
    zltail 記錄壓縮列表表尾節點距離壓縮列表的起始地址有多少個字節:通過這個偏移量,程序無需遍歷整個壓縮列表就可以確定表尾節點的地址
    zllen 記錄了壓縮列表包含的節點數量
    zlend 特殊值oxFF(十進制255),用於標記壓縮列表的末尾
  • skiplist編碼
    skiplist編碼使用跳躍表和字典實現底層數據結構
    字典(dict)爲有序集合構造了一個成員和分值之間的映射,字典中的每個鍵保存了元素成員,字典的值保存了元素的分值。通過字典,可以以O(1)的時間複雜度查找成員對應的分值。
    因爲字典的鍵是唯一的,字典與跳躍表之間共享元素的指針,所以不會存在重複元素。排序是在跳躍表中實現的。

    跳躍表的相關內容參考:跳躍表

參考:W3Cschool 和 Redis設計與實現(黃健宏)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章