Redis設計與實現(一)

2021-09-12 01:27:28 字數 2154 閱讀 1398

redis是一種現在挺火的一種nosql資料庫,它一般被用作快取。

比如我們可以在redis客戶端敲

redis> set msg "helloredis"
那麼就會在redis資料庫中建立乙個新的鍵值對,keg是msg,value是helloredis,兩個都是sds。

又比如在redis客戶端敲

redis>rpush number 1 2 3
這也就是乙個list物件(列表物件),numbe為鍵,1,2,3為值。經過這幾個小的例子你會發現redis的用法很簡單,sds還可以被用來作緩衝區(buffer):aof模組的aof緩衝區和客戶端狀態中的輸入緩衝區。

說了這麼多的sds,那麼到底什麼是sds,sds又是怎麼實現的呢,那它又和我們傳統的字串有什麼區別呢?

我們可以用c的結構體來表示sds的定義資訊

struct sds
那這些都是代表什麼意思呢?

len:用來記錄字串的長度,也就是buf已使用的位元組數量

free:用來記錄buf中剩餘的數量

buf:是乙個char陣列,用來儲存字串的每個字元,字串最後必須是乙個空字元』\0』,不占用空間但是占用位置。這些新增字串字尾都是由redis的內部函式來實現。

不止這一點redis的設計和c很像,redis還有很多和c相同的地方,因為這樣就可以直接重用一些c寫好的函式。

現在是不是對sds有一些了解了,從結構可以看出它比c中的字串多了len和free,這寫引數可以決定怎樣的效能呢?

redis獲取字串長度時間複雜度低,保證了效率

sds不會造成緩衝去溢位

這個原因的實質還是因為沒有len,我們假設在計算機記憶體中按順序排列著s1,s2字串,s2緊跟著s1字串。如果是普通字串進行拼接操作

sds會很大程度減少記憶體重分配次數

為什麼這麼說呢?相信大家以前也做過字串修改的函式,我們當時函式底層是怎樣的呢?在我們每次修改字串時系統都會執行記憶體重分配演算法,如果不經常修改的話這都不是問題(前提是不粗心,不然增的時候可能會造成記憶體溢位,刪的時候可能會造成記憶體洩漏),但是資料庫就不一樣,因為資料庫的修改操作很頻繁,因此redis採用的快取策略。

二進位制安全

這個也是c中的字串中比較難受的事情了,比如我們輸入一串數字再加上空格再加上一串數字,c就只會把它的前一段寫進去,因為c判斷結束的標識是空字元。但是redis就不會出現這種問題,輸入進去什麼樣子,輸出出來就是什麼樣子,為什麼呢?歸根結底還是因為有len,因為它可以記住個數而不是一味的根據空字元來判斷是不是結束了,因此它上邊就可以存任何型別的東西。比如傳一串二進位制字串,c可能得需要很複雜的處理,但是redis根據sds的定義就可以很輕鬆的解決這個問題。那redis可以不給末尾加\0也可以實現為什麼要加,還是因為它可以重用一些c的庫函式。

總結:sds相對於普通字串的優點(歸根結都還是結構體的設計問題)

因為c裡沒有鍊錶庫,因此redis就自己實現了鍊錶,那煉表在redis中扮演乙個什麼的角色呢?它在redis中的應用非常廣泛,比如鍊錶鍵,發布與訂閱,慢查詢,監視器等功能,redis伺服器本身還使用鍊錶來儲存客戶端的狀態資訊。

鍊錶的操作就很簡單了,因為它就和糖葫蘆一樣乙個乙個穿成一串。沒有寫過或者了解鍊錶的可以去一些資料結構或者演算法導論等一些書上去參考更詳細的,我這就講個中心意思。

設計資料結構模型,給node模型加上前驅和後記和節點的值。

typedef struct listnodelistnode;
然後就通過指標操作頭插或尾插進行連線成乙個雙向鍊錶。

但是redis是以高效能著稱的,按照上述設計那不就是乙個普通的單鏈表麼,因此個資料結構仍有改進的空間。redis後來就自己設計了如下結構的節點結構。

typedef struct listlist;
這種相對於上一種的優勢所在是帶有長度計數器,和節點的特定函式。

可以總的來說一下redis的鍊錶實現的特性:

1.雙向鍊錶獲取前驅和後繼的時間複雜度都是o(1)

2.是乙個沒有頭節點的鍊錶,最小是空

3.帶有表頭和表尾,獲取頭和尾時間複雜度為o(1)

4.多種功能:幾個特殊設定的函式,可用於儲存各種不同型別的值

雖然感覺上述這些並不是很難懂,但是它都設計的很巧妙,對查詢和修改都優化了不少。

Redis 設計與實現

本書的目標是以簡明易懂的方式講解 redis 的內部執行機制,通過閱讀本書,你可以了解到 redis 從資料結構到伺服器構造在內的幾乎所有知識。為了保證內容的簡潔性,本書會盡量以高抽象層次的角度來觀察 redis 並將 的細節留給讀者自己去考究。如果讀者只是對 redis 的內部運作機制感興趣,但並...

redis設計與實現

物件所使用的底層資料結構 編碼常量 object encoding 命令輸出 整數redis encoding int int embstr編碼的簡單動態字串 sds redis encoding embstr embstr 簡單動態字串 redis encoding raw raw 字典redis...

《redis設計與實現》

提高系統架構的效能,增加快取層是常見的優化方式,redis和memcache是當前採用較多的快取元件,redis被稱為資料結構資料庫 redis和memcache的區別 redis和memcahce都是基於記憶體的key value儲存 memcache的事件模型是多執行緒reactor模型,效能更...