首頁> 資料庫> Redis> 主體

Redis中有序集合的內部如何實現

WBOY
發布: 2023-05-26 19:25:39
轉載
948 人瀏覽過

有序集合的內部實作

有兩種內部實作方式可以用於有序集合,分別是壓縮列表(ziplist)和跳躍表(skiplist)。接下來,我們分別進行詳細的了解。

以壓縮列表作為內部實作

當有序集合的元素個數小於zset-max-ziplist-entries(預設為128個),而每個元素成員的長度小於zset-max-ziplist-value(預設為64位元組)的時候,使用壓縮列表作為有序集合的內部實作。

每個集合元素由兩個緊挨著的兩個壓縮列表結點組成,其中第一個結點保存元素的成員,第二個結點保存元素的分支。透過按照分數的大小順序將壓縮列表中的元素依序排列在一起,可以有效地減少記憶體空間的使用。

舉個例子,我們使用zadd指令建立一個以壓縮列表為實現的有序集合:

127.0.0.1:6379> zadd one-more-zset 1 one 2 two 3 three (integer) 3 127.0.0.1:6379> zrange one-more-zset 0 -1 1) "one" 2) "two" 3) "three" 127.0.0.1:6379> object encoding one-more-zset "ziplist"
登入後複製
登入後複製

以跳躍表作為內部實作

當有序集合的元素個數大於等於zset-max-ziplist-entries(預設為128個),或每個元素成員的長度大於等於zset-max-ziplist-value(預設為64位元組)的時候,使用跳躍表作為有序集合的內部實現。

此時,在有序集合中其實包含了兩個結構,一個是跳躍表,另一個是哈希表。

在跳躍表中,所有元素都依照從小到大的順序排列。跳躍表的結點中的object指標指向元素成員的字串對象,score保存了元素的分數。透過跳躍表,Redis可以快速地對有序集合進行分數範圍、排名等操作。

在雜湊表中,為有序集合建立了一個從元素成員到元素分數的對應。在鍵值對中,鍵是字串物件並指向元素成員,而值則保存了元素的分數。透過哈希表,Redis可以快速找到指定元素的分數。

雖然有序集合同時使用跳躍表和雜湊表,但是這兩個資料結構都使用指標共享元素中的成員和分數,不會額外的記憶體浪費。

舉個例子,我們使用zadd指令來建立一個以跳躍表為實現的有序集合:

127.0.0.1:6379> zadd one-more-zset 1 long-long-long-long-long-long-long-long-long-long-long-long-long-long (integer) 1 127.0.0.1:6379> zrange one-more-zset 0 -1 1) "long-long-long-long-long-long-long-long-long-long-long-long-long-long" 127.0.0.1:6379> object encoding one-more-zset "skiplist"
登入後複製

內部實作的轉換

當一個有序集合是以壓縮列表作為內部實現時,再向這個有序集合添加較長的元素成員,或向這個有序集合的元素個數過多時,那麼這個有序集合就會轉換為以跳躍表作為內部實現。使用壓縮列表作為內部實現的有序集合不會轉換為跳躍表。

舉個例子,我們先創建一個以壓縮列表作為內部實現的有序集合:

127.0.0.1:6379> zadd one-more-zset 1 one 2 two 3 three (integer) 3 127.0.0.1:6379> zrange one-more-zset 0 -1 1) "one" 2) "two" 3) "three" 127.0.0.1:6379> object encoding one-more-zset "ziplist"
登入後複製
登入後複製

然後,再向它添加一個較長成員的元素,它就是轉換為以跳躍表作為內部實現:

127.0.0.1:6379> zadd one-more-zset 4 long-long-long-long-long-long-long-long-long-long-long-long-long-long (integer) 1 127.0.0.1:6379> zrange one-more-zset 0 -1 1) "one" 2) "two" 3) "three" 4) "long-long-long-long-long-long-long-long-long-long-long-long-long-long" 127.0.0.1:6379> object encoding one-more-zset "skiplist"
登入後複製

然後,再把那一個較長成員的元素從有序集合中移除,有序集合依然是以跳躍表作為內部實現:

127.0.0.1:6379> zrem one-more-zset long-long-long-long-long-long-long-long-long-long-long-long-long-long (integer) 1 127.0.0.1:6379> zrange one-more-zset 0 -1 1) "one" 2) "two" 3) "three" 127.0.0.1:6379> object encoding one-more-zset "skiplist"
登入後複製

以上是Redis中有序集合的內部如何實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!