Redis深入之資料結構

weixin_34119545發表於2015-12-23

Redis主要資料結構

連結串列

Redis使用的C語言並沒有內建這樣的資料結構,所以Redis構建了自己的連結串列實現。列表鍵的底層實現之中的一個就是連結串列,一個列表鍵包括了數量比較多的元素,列表中包括的元素都是比較長的字串,Redis就會使用連結串列作為列表鍵的底層實現。

除了連結串列鍵之外。Redisserver本身還使用連結串列來儲存多個client的狀態資訊。使用連結串列來構建client輸出緩衝區。

eg: redis> LLEN integers

(integer)1024

integers列表鍵包括了從1到1024共1024個整數,integers列表鍵的底層實現就是一個連結串列,連結串列中的每一個節點都儲存了一個整數值。

 

每一個連結串列節點由一個listNode結構來表示,每一個節點都有一個指向前置節點和後置節點的指標。Redis的連結串列實現是雙端連結串列。

每一個連結串列使用一個list結構來表示,這個結構帶有表頭節點指標、表尾節點指標,以及連結串列長度等。

由於連結串列表頭節點的前置節點和表尾節點的後置節點都指向NULL,所以Redis的連結串列實現是無環連結串列。

字典

字典。符號表或對映,儲存鍵值對的抽象資料結構

Redis構建了自己的字典。字典使用雜湊表作為底層實現,每一個字典帶有兩個雜湊表。一個平時使用,還有一個僅在進行rehash時使用。一個雜湊表裡面能夠有多個雜湊表節點。而每一個雜湊表節點就儲存了字典中的一個鍵值對。Redis使用MurmurHash2演算法來計算鍵的雜湊值。

兩個或以上數量的鍵被分配到了雜湊表陣列的同一個索引上面。這些鍵發生了衝突。Redis的雜湊表使用鏈地址法來解決鍵衝突。

隨著操作的不斷執行,雜湊表儲存的鍵值對會逐漸地增多或者降低。為了讓雜湊表的負載因子維持在一個合理的範圍之內,擴充套件和收縮雜湊表的工作能夠通過執行rehash(又一次雜湊)操作來完畢,須要將現有雜湊表包括的全部鍵值對rehash到新雜湊表裡面。而且rehash過程並非一次性完畢的,而是漸進式地完畢的。

跳躍表

跳躍表是一種有序資料結構,它通過在每一個節點中維持多個指向其他節點的指標。從而達到高速訪問節點的目的。

redis>ZRANGE fruit-price 0 2 WITHSCORES

fruit-price有序集合的全部資料都儲存在一個跳躍表裡面,每一個跳躍表節點都儲存了一款水果的價錢資訊,全部水果按價錢的高低從低到高在跳躍表裡面排序。

Redis使用跳躍表作為有序集合鍵的底層實現之中的一個,假設一個有序集合包括的元素數量比較多。又或者有序集合中元素成員是比較長的字串時。Redis就會使用跳躍表來作為有序集合鍵的底層實現。Redis僅僅在兩個地方用到了跳躍表。一個是實現有序集合鍵。還有一個是在叢集節點中用作內部資料結構。

Redis的跳躍表實現由zskiplist和zskiplistNode兩個結構組成,當中zskiplist用於儲存跳躍表資訊(比方表頭節點、表尾節點、長度)。而zskiplistNode則用於表示跳躍表節點。

整數集合

整數集合是集合鍵的底層實現之中的一個,當一個集合僅僅包括整數值元素,而且這個集合的元素數量不多時,Redis就會使用整數集合作為集合鍵的底層實現。

redis > SADD numbers 1 3 5 7 9 

壓縮列表是一種為節約記憶體而開發的順序型資料結構。

redis>RPUSH 1st 1 3 5 10086 "hello" "world"

壓縮列表由一系列特殊編碼的連續記憶體塊組成的順序型資料結構。

壓縮列表被用作列表鍵和雜湊鍵的底層實現之中的一個

壓縮列表能夠包括多個節點。每一個節點能夠儲存一個位元組陣列或者整數值。

加入新節點到壓縮列表,或者從壓縮列表中刪除節點。可能會引發連鎖更新操作,但這樣的操作出現的機率並不高。

相關文章