redis就是記憶體中維持乙個巨大的字典,字典的key節點及value節點是乙個個資料結構。
在這裡簡單介紹一下redis用到的資料結構。
[b]1.簡易動態字串(sds)[/b]
redis沒有使用傳統的c字串形式,取而代之的是自己實現了乙個簡單動態字串簡易動態字串結構,簡稱為sds(****** dynamic strings)。
sds相容c字串的同時,帶來了二進位制安全、計算更有效率、杜絕緩衝區溢位等優點。
struct sdshdr ;
"hello"的儲存方式在內部就可能(小夥伴們考慮一下為啥是可能呢?)表示成下面的形式
[img]
[b]2.雙鏈表(adlist)[/b]
雙鏈表是乙個基本的資料結構,樣子就像一串回形針。
redis中的雙鏈表跟小夥伴們在《資料結構》中學到的雙鏈表一模一樣,在此就不詳細介紹了。
放個示意圖
[img]
[b]3.字典(dict)[/b]
作為key-value資料庫,上面提到過整個redis就是乙個巨大的字典,字典的設計決定了此類產品的成敗。
redis的字典由字典型別特定函式和2個雜湊表表組成。特定函式包括計算雜湊值、複製鍵\值等一些列函式組成,兩個雜湊表用來實現漸進式 rehash。
typedef struct dict dict;
雜湊表hash演算法採用比較流行的murmurhash2演算法,對於規律性較強的key,節點更加「分布均勻」。
用鍊錶法處理hash碰撞,將多個雜湊值相同的節點串連在一起。
漸進式 rehash是redis字典特性,防止一次rehash導致系統資源使用增高可能導致的卡死。
非rehash時,資料會放到雜湊表ht[0];rehash時,新插入的資料會放置到ht[1],同時每次字典操作都會從ht[0]移動一定數量的雜湊表節點到ht[1],直到ht[0]節點數變為0,
然後執行ht[0]=ht[1],重置ht[1]。
示意圖為正在rehash的字典的示意
[img]
[b]4.跳表(skiplist)[/b]
跳表是種偷懶的設計,用來替代平衡樹,跳表的演算法有同平衡樹一樣的漸進的預期時間邊界,並且更簡單、更快速和使用更少的空間。
跳表是按照層級來建造的,每層皆是乙個鍊錶,上層是下層的快速跑道可以更快的定位資料所在的位置範圍,查詢資料時逐層定位縮小範圍直至範圍變為1或者0。
typedef struct zskiplistnode level;
} zskiplistnode;
各個level節點記錄前進指標的同時也會記錄到下乙個節點的跨度,遍歷跳表只需按照跨度等於1從頭到尾訪問節點即可。
[img]
[b]5.壓縮列表(ziplist)[/b]
壓縮列表是redis為解決記憶體而設計的儲存方式,到滿足一定的條件(如元素的個數少、key或者value的長度短)的情形下,list和字典都有可能使用壓縮列表儲存。
壓縮列表的儲存結構如下:
[img]
zlbytes 記錄整個壓縮表占用的位元組數
zltail 記錄壓縮列表尾節點距離壓力表第乙個位元組位址的偏移
zllen 表示壓縮節點的個數
zlentry 為壓縮表節點
zlend 壓縮表結尾特殊位元組,為0xff
zlentry的結構如下
typedef struct zlentry zlentry;
6.整數集合(intset)
當集合中只有整數時,redis會使用下面的結構來儲存這些整數。
typedef struct intset intset;
[img]
redis內部資料結構的資料結構
redis對外的公眾的資料結構有五種string,list,set,hash,zset 編碼常量 編碼所對應的底層資料結構 redis encoding int long 型別的整數 redis encoding embstr embstr 編碼的簡單動態字串 redis encoding raw ...
Redis學習筆記 Redis內部資料結構
redis內部資料結構 redis和其他key value資料庫的很大區別是它支援非字串型別的value值。它支援的value值的型別如下 sds dynamic string 簡單動態字串 雙端鍊錶 字典 dictionary map associative array 跳躍表 skiplist ...
Redis內部資料結構實現解析
redis目前在key value儲存以及快取系統中有著非常廣泛的應用,且以高效快速著稱。不同於其他key value資料庫,redis提供了豐富的資料結構型別,value可以是字串 列表 雜湊和有序集等,為使用者操作帶來了極大的便利。本文希望通過分析其內部資料結構及演算法的實現機制,來揭示其高效能...