跳躍表(skiplist)是一種有序資料鏈表結構, 它通過在每個節點中維持多個指向其他節點的指標, 從而達到快速訪問節點的目的。查詢平均效能為o(logn),最壞的情況會出現o(n)情況,而redis中的zset在資料較多的時候底層就是採用跳躍表去實現的,元素較少的時候會進行小物件壓縮採用壓縮列表實現。
小物件壓縮條件:
hash-max-zipmap-entries 512 # hash 的元素個數超過 512 就必須用標準結構儲存hash-max-zipmap-value 64 # hash 的任意元素的 key/value 的長度超過 64 就必須用標準結構儲存
list-max-ziplist-entries 512 # list 的元素個數超過 512 就必須用標準結構儲存
list-max-ziplist-value 64 # list 的任意元素的長度超過 64 就必須用標準結構儲存
zset-max-ziplist-entries 128 # zset 的元素個數超過 128 就必須用標準結構儲存
zset-max-ziplist-value 64 # zset 的任意元素的長度超過 64 就必須用標準結構儲存
set-max-intset-entries 512 # set 的整數元素個數超過 512 就必須用標準結構儲存
從上述圖我們可以看出跳躍表有以下幾個特點:
1.跳躍表的每個節點都有多層構成。
2.跳躍表存在乙個頭結點,該頭結點有64層結構,每層都包含指向下個節點的指標,指向本層下個節點中間所跨越的節點個數跨度(span)。
3.除頭結點以外,層高最搞的節點為該條約表的level,圖中的跳躍表level為3。
4.每層都是乙個有序鍊錶。
5.最底層的有序鍊錶包含所有的節點數,也即是整個跳躍表的長度。
跳躍表每個節點都維護了多個指向其他節點的指標,所以在進行查詢、更新、刪除等操作的時候不需要進行整條鍊錶的遍歷,可以通過維護的指標過濾掉中間的很多節點,從而達到很快速的訪問效果,一般情況來說跳躍表的效能能與平衡樹相媲美的,而且跳躍表實現較為簡單,所以這也是redis為什麼採用跳躍表來作為zset底層的資料結構實現。
跳躍表的查詢,跳躍表有多層的情況下查詢複雜度為o(logn),如果跳躍表就一層那麼查詢複雜度會上公升為o(n),接下來我們就用圖1的例項來模擬下查詢score為70的節點的具體查詢過程。
如圖所示我們需要找到score為70的節點,查詢首先從header開始,因為level為3我們先從l2開始往後開始遍歷,查詢到第乙個節點,發現score比70小,繼續往後遍歷查詢到第五個節點,發現score比70到,於是從當前節點往下一層進行查詢,查詢到節點3,以此類推,最終查詢到score為70的節點。
插入過程:
跳躍表插入節點的時候,首先需要通過score找到自己的位置,也就是需要先走一步查詢過程,找到新節點所處的位置的時候就建立乙個新節點,並對新節點分配乙個層數(這裡層數的分配redis採用的是random隨機機制,分配層數從1開始,每次晉公升為上一層的概率為0.25),層數分配完了之後將前後指標進行賦值將新節點與舊節點串起來,如果層數大於當前的level還需要進行level的更新操作。
更新過程:
更新過程會稍微複雜一些,更新其實就是插入,只不過插入的時候發現value已經存在了,只是需要調整一下score值,如果更新的score值不會帶來位置上的改變,那麼直接更新score就行不需要進行調整位置,但是如果新score會導致排序改變,那麼就需要調整位置了,redis採用的方式比較直接就是先刪除這個元素然後再插入這個元素即可,前後需要兩次路徑搜尋。
參開文獻:
1.redis 深度歷險:核心原理與應用實踐
Redis資料結構 跳躍表
跳躍表是一種有序資料結構,它通過在每個節點中維持多個指向其他節點的指標,從而達到快速訪問節點的目的。redis使用跳躍表作為有序集合鍵的底層實現之一,如果乙個有序集合包含的元素數量比較多,又或者有序集合中的元素的成員是比較長的字串時,redis就會使用跳躍表作為有序集合鍵的底層實現。redis的跳躍...
Redis資料結構 skiplist(跳躍表)
跳躍表在redis中主要用於有序集合鍵的實現,其他地方沒怎麼用到,但是這種資料結構在面試的時候經常會問到,因為它作為一種查詢時間複雜度為o logn 的特殊的鍊錶,效率堪比紅黑樹或平衡樹,而實現難度卻遠小於它們。下面分3個模組講解redis的跳躍表實現 一 跳躍表的應用場景 在redis中,當有序集...
Redis資料結構之跳躍表
跳躍表在每個節點中維持多個指向其他節點的指標,可快速訪問節點且有序 跳躍表查詢複雜度為平均o logn 最壞o n 跳躍表使用於有序集合元素數量比較多或者元素是比較長的字串的場景。跳躍表節點 typedef struct zskiplistnode level 後退指標 struct zskipli...