深入淺出Redis redis底層資料結構(下)

2022-07-05 00:27:11 字數 3352 閱讀 7284

學習使用redis,其實並不需要去研究其底層資料的實現。我們只需要了解他有哪些常用的資料型別,然後熟練使用,就可以很好的掌握redis 這個工具了。但是這樣的學習方法只適合redis 的入門,「工欲善其事必先利其器」,我們想要用好redis,則必須深入了解redis 的底層到底是如何實現的,我們在選擇資料結構的時候才能做出正確的選擇。

在這裡我們簡單回顧一下他們的特點:

1、動態字串sds:區別於c語言字串,具有良好的伸縮性,在獲取字串長度,字串修改,防止快取區溢位等效能都比c語言字串好

2、鍊錶:順序儲存物件資訊,有用於快取鍊錶長度的屬性,在插入刪除物件功能中有良好效能,避免環的產生

3、字典:key-value 儲存方式,通過hash值計算,判斷key的儲存,當容量過大,會通過rehash重新分配字典大小

跳躍表(skiplist)是一種有序資料結構,它通過在每個節點中維持多個指向其他節點的指標,從而達到快速訪問節點的目的。跳躍表是一種隨機化的資料,跳躍表以有序的方式在層次化的鍊錶中儲存元素,效率和平衡樹媲美 ——查詢、刪除、新增等操作都可以在對數期望時間下完成,並且比起平衡樹來說,跳躍表的實現要簡單直觀得多。

redis 只在兩個地方用到了跳躍表,乙個是實現有序集合鍵,另外乙個是在集群節點中用作內部資料結構

redis 的跳躍表 主要由兩部分組成:zskiplist(鍊錶)和zskiplistnode (節點)

5.2.1 zskiplistnode(節點) 資料結構:

typedef struct

zskiplistnode level;

//後退指標

struct zskiplistnode *backward;

//分值

double

score;

//成員物件

robj *obj;

}

1、層:level 陣列可以包含多個元素,每個元素都包含乙個指向其他節點的指標。

2、前進指標:用於指向表尾方向的前進指標

3、跨度:用於記錄兩個節點之間的距離

4、後退指標:用於從表尾向表頭方向訪問節點

5、分值和成員:跳躍表中的所有節點都按分值從小到大排序。成員物件指向乙個字串,這個字串物件儲存著乙個sds值

5.2. zskiplist 資料結構:

從結構圖中我們可以清晰的看到,header,tail分別指向跳躍表的頭結點和尾節點。level 用於記錄最大的層數,length 用於記錄我們的節點數量。

《redis 設計與實現》中這樣定義整數集合:「整數集合是集合建的底層實現之一,當乙個集合中只包含整數,且這個集合中的元素數量不多時,redis就會使用整數集合intset作為集合的底層實現。」

我們可以這樣理解整數集合,他其實就是乙個特殊的集合,裡面儲存的資料只能夠是整數,並且資料量不能過大。

1、encoding:用於定義整數集合的編碼方式

2、length:用於記錄整數集合中變數的數量

3、contents:用於儲存元素的陣列,雖然我們在資料結構圖中看到,intset將陣列定義為int8_t,但實際上陣列儲存的元素型別取決於encoding

在上述資料結構圖中我們可以看到,intset 在預設情況下會幫我們設定整數集合中的編碼方式,但是當我們存入的整數不符合整數集合中的編碼格式時,就需要使用到redis 中的公升級策略來解決

intset 中公升級整數集合並新增新元素共分為三步進行:

1、根據新元素的型別,擴充套件整數集合底層陣列的空間大小,並為新元素分配空間

2、將底層陣列現有的所有元素都轉換成新的編碼格式,重新分配空間

3、將新元素加入到底層陣列中

比如,我們現在有如下的整數集合:

我們現在需要插入乙個32位的整數,這顯然與整數集合不符合,我們將進行編碼格式的轉換,並為新元素分配空間:

第二步,將原有資料他們的資料型別轉換為與新資料相同的型別:(重新分配空間後的資料)

第三部,將新資料新增到陣列中:

6.3.1 整數集合公升級的好處

1、提公升靈活性

2、節約記憶體

整數集合是集合建的底層實現之一

整數集合的底層實現為陣列,這個陣列以有序,無重複的正規化儲存集合元素,在有需要時,程式會根據新新增的元素型別改變這個陣列的型別

公升級操作為整數集合帶來了操作上的靈活性,並且盡可能地節約了記憶體

整數集合只支援公升級操作,不支援降級操作

壓縮列表是列表鍵和雜湊鍵的底層實現之一。當乙個列表鍵只把汗少量列表項,並且每個列表項要麼就是小整數,要麼就是長度比較短的字串,那麼redis 就會使用壓縮列表來做列表鍵的底層實現。

乙個壓縮列表的組成如下:

1、zlbytes:用於記錄整個壓縮列表占用的記憶體位元組數

3、zllen:記錄了壓縮列表包含的節點數量。

4、entryx:要說列表包含的各個節點

5、zlend:用於標記壓縮列表的末端

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

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

壓縮列表可以包含多個節點,每個節點可以儲存乙個位元組陣列或者整數值

新增新節點到壓縮列表,可能會引發連鎖更新操作。

深入淺出sizeof

int佔 位元組,short佔 位元組 1.0 回答下列問題 答案在文章末尾 1.sizeof char 2.sizeof a 3.sizeof a 4.strlen a 如果你答對了全部四道題,那麼你可以不用細看下面關於sizeof的論述。如果你答錯了部分題目,那麼就跟著我來一起 關於sizeof...

深入淺出ShellExecute

ipconfig c log.txt應如何處理?二樓的朋友,開啟拔號網路這樣 shellexecute null,open c windows rundll32.exe shell32.dll,control rundll c windows system telephon.cpl null,sw ...

深入淺出ShellExecute

深入淺出shellexecute譯者 徐景周 原作 nishant s q 如何開啟乙個應用程式?shellexecute this m hwnd,open calc.exe sw show 或shellexecute this m hwnd,open notepad.exe c mylog.log...