redis的sorted set 底層是由skiplist,dict,ziplist來實現的。
在reids.config中有兩個配置
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
sorted set是乙個有序集合,當資料較少時,sorted set是由乙個ziplist來實現的。當資料多的時候,sorted set是由乙個zset來實現的,它包括dict和乙個skiplist。其中dict用來查詢data到score的關係,而skiplist用來根據score做範圍查詢。這個配置的意思是當sorted set中的元素個數的數目超過128即ziplist資料項超過256的時候。或者sorted set中插入的任意資料長度超過64的時候,sorted set從ziplist轉為zset。
redis的skiplist是做了優化了的的跳躍表。
雜湊表,平衡樹和跳躍表都可以用來查詢。其中平衡樹和跳躍表有序,雜湊表無序。因此雜湊表上只能做單個的key查詢。不能做範圍查詢。做範圍查詢的時候,平衡樹比跳躍表複雜,平衡樹的插入和刪除可能會引發子樹的調整,而redis改進後的跳躍表插入和刪除只需要修改相鄰節點的指標。
跳躍表是乙個有序鍊錶。傳統的鍊錶查詢從頭開始逐個查詢,時間複雜度為o(n),插入資料會有相同的查詢過程。跳躍表是在每隔2個節點之間增加指標,指標指向下下個節點,新增指標形成新的鍊錶。並且可以以同樣的方式增加指標形成第三層鍊錶。這種方式提高了查詢速度,上面每一層鍊錶長度是下面一層的一半,查詢起來類似二分查詢,查詢的複雜度降到了o(log n)。但是這種方式在增加和刪除節點的時候要調整所有層的鍊錶。而redis對跳躍表進行了改動,其skiplist的每個節點的層數是隨機出來的,修改的時候只修改變動節點前後的指標,不需要對其他節點進行調整。這樣就降低了插入和刪除操作的複雜度,使其skiplist的效能優於平衡樹。
而且,redis的skiplist的第一層鍊錶是個雙向鍊錶,這樣可以方便以倒序方式搜尋。
例如:zsccore,根據key查詢score,由dict完成。時間複雜度為o(1) 。
zrevrank,檢視key的排名,先由dict中由資料查到分數,再拿分數到skiplist中查出排名。時間複雜度為o(log n)。
zrevrange,檢視排行榜,由ziplist完成。時間複雜度為o(log (n)+m),m為查詢返回的元素個數。
下面是zset的定義:
typedef struct zset zset;
skiplist的定義:
#define zskiplist_maxlevel 32
#define zskiplist_p 0.25
typedef struct zskiplistnode level;
} zskiplistnode;
typedef struct zskiplist zskiplist;
redis內部資料結構的資料結構
redis對外的公眾的資料結構有五種string,list,set,hash,zset 編碼常量 編碼所對應的底層資料結構 redis encoding int long 型別的整數 redis encoding embstr embstr 編碼的簡單動態字串 redis encoding raw ...
Redis內部資料結構總結(2)dict
dict是redis乙個非常重要的基礎資料結構,dict用來維護key和value對映關係的資料結構,與很多語言中的map或者dictionary類似。redis的乙個database中所有key到value的對映,就是乙個dict來維護的。另外,當redis中的hash結構資料較多時,hash的底...
redis內部資料結構總結(7)intset
redis裡面使用intset是為了實現集合 set 這種對外的資料結構。set結構類似於數學上的集合的概念,它包含的元素無序,且不能重複。redis裡的set結構還實現了基礎的集合並 交 差的操作。與redis對外暴露的其它資料結構類似,set的底層實現,隨著元素型別是否是整型以及新增的元素的數目...