Redis深入之資料結構,redis資料結構
Redis主要資料結構
鏈表
Redis使用的C語言並沒有內建這種資料結構,所以Redis構建了自己的鏈表實現。列表鍵的底層實現之一就是鏈表,一個列表鍵包含了數量比較多的元素,列表中包含的元素都是比較長的字串,Redis就會使用鏈表作為列表鍵的底層實現。除了鏈表鍵之外,Redis伺服器本身還使用鏈表來儲存多個用戶端的狀態資訊,使用鏈表來構建用戶端輸出緩衝區。
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"
壓縮列表由一系列特殊編碼的連續記憶體塊組成的順序型資料結構。
壓縮列表被用作列表鍵和雜湊鍵的底層實現之一
壓縮列表可以包含多個節點,每個節點可以儲存一個位元組數組或者整數值。
添加新節點到壓縮列表,或者從壓縮列表中刪除節點,可能會引發連鎖更新操作,但這種操作出現的幾率並不高。