跳躍表:
跳躍表是一種有序資料結構,通過在每個節點維持多個指向其他節點的指標,達到快速訪問節點的目的。redis使用跳躍表作為有序集合鍵的實現,如果乙個有序集合包含額元素數量比較多,又或者有序集合中元素的成員是比較長的字串時,redis會使用
跳躍表作為有序集合鍵的實現。
redis只在有序集合鍵和集群節點中用作內部資料結構。
跳躍表zskiplistentryx
previous_entry_length 儲存的是前乙個位元組的長度,如果前乙個節點的長度<254位元組,那麼previous_entry_length屬性的長度為一位元組(注:前乙個節點的長度》=254位元組,指實際分配記憶體空間大於254位元組,而我們這裡所說的屬性長度為一位元組僅僅是用來記錄這個長度值,相當於記錄數字,這裡容易弄混),如果前乙個節點長度》=254位元組,那麼previous_entry_length屬性的長度為5位元組,其中屬性的第一位元組會被設定為0xee(十進位制254),而之後的四個位元組則用於儲存前一位元組的長度
壓縮列表可以通過表尾指標所指向表尾的節點減去當前及節點的previous_entry_length值,即可以得到前乙個節點所在位置,這就是壓縮列表從表尾向表頭的遍歷操作
壓縮列表存在連鎖更新問題:即如果在表頭插入乙個大於254位元組長度的節點,原來表頭節點的previous_entry_length屬性僅為一位元組無法儲存現表頭長度,則需要變化擴充套件previous_entry_length屬性為5位元組,如果恰好當前節點長度介於250到253之間,則擴充套件後使得當前節點長度》=254位元組,使得下乙個節點也無法儲存,繼續擴充套件下乙個節點可能出現連鎖反應,引發由記憶體空間重分配引發的效能問題。
redis物件:
redis沒有使用之前講到的資料結構來實現鍵值對資料庫,而是基於這些資料結構建立了乙個物件系統,系統包含了 字串物件,列表物件,雜湊物件,集合物件,有序集合物件,五種型別
reredis使用物件來表示資料庫中的鍵和值,每次使用reids的資料庫建立乙個鍵值對時,至少會建立兩個物件,
redisobject結構如下所示:
redisobjectzset
對於zskiplist使用跳躍表節點的score屬性儲存分值,object屬性儲存元素成員
對於字典使用,字典的鍵儲存了元素的值,字典的值儲存了元素的得分
這樣的目的是使用zskiplist可以降低範圍查詢的時間複雜度:如執行zrank,zrange命令
使用dict的原因是可以以o(1)的時間複雜度的到元素的分值,如果上述兩隻結構只使用乙個的話,必然會導致某乙個命令的時間複雜度上公升。
有序集合物件可以同時滿足一下兩個條件時物件會使用ziplist編碼:
有序集合物件儲存元素數量小於128
有序集合儲存的所有元素成員的長度都小於64位元組
redisobject物件中記憶體**:
redis在自己的物件系統中構建了乙個引用計數技術實現記憶體的**機制,通過這一機制,程式通過跟蹤物件的引用計數資訊,在適當的時候自動釋放物件進行記憶體**
每個物件的引用計數用redisobject物件的refcount 屬性記錄
建立乙個新物件時,引用計數值會被初始化為1
當物件被乙個新程式使用時,它的引用計數值會被增1
當物件不再被乙個程式使用時,它的引用計數值減一
當物件的引用計數值為0時,物件占用的記憶體會被釋放
redisobject物件中物件共享:
物件的引用計數屬性還帶有物件共享的作用,如果鍵a建立了乙個包含整數值100的字串物件作為值物件,如果鍵b也要建立乙個同樣儲存了整數值100的字串物件作為值物件,
那麼鍵b則會和a共享乙個字串物件
實現步驟:
將資料庫鍵的值指標指向乙個現有的值物件,將被共享的值物件的引用計數增1
目前來說redis會在初始化伺服器時,建立一萬個字串物件,這些物件包含了從1到9999的所有整數值,當伺服器需要用到0到9999的字串物件時,伺服器就會使用這些共享物件,而不是建立新物件
物件的空轉時長:
redisobject.lru屬性:該屬性記錄了物件最後一次被命令程式訪問的時間。
通過使用object idletime 命令可以列印出給定鍵的空轉時長,這一空轉時長就是通過將當前時間減去鍵的值物件的lru時間計算得到
鍵的空轉時長還有乙個作用就是如果伺服器開啟了maxmemory選項,並且伺服器用於記憶體**的演算法為volatile-lru或者allkeys-lru,那麼當伺服器占用的記憶體數超過了maxmemory選項所設定的上限值時,
空轉時長較高的那部分鍵會優先被伺服器釋放,從而**記憶體
Redis3 鍊錶
每個鍊錶節點使用乙個adlist.h listnode結構來表示 多個listnode可以通過prev和next指標組成雙端鍊錶,如下圖所示 雖然僅僅使用多個listnode結構就可以組成鍊錶,但使用adlist.h list來持有鍊錶的話,操作起來會更方便 list結構為鍊錶提供了表頭指標head...
Redis設計與實現之跳躍表
一 定義 跳躍表 skiplist 是一種有序的資料結構,它通過在每個節點中維持多個指向其他節點的指標,從而達到快速訪問節點的目的 跳躍表支援平均o logn 最壞o n 複雜度的節點查詢,還可以通過順序性操作來批量處理節點。redis使用跳躍表作為有序集合鍵的底層實現之一,若乙個有序集合包含的元素...
Redis設計與實現 四 跳躍表
跳躍表是乙個有序的資料結構,跳躍是通過在當前節點儲存多個其他節點的指標,來達到跳躍的目的。它支援平均o logn 最差o n 複雜度的節點查詢,還可以通過順序性來批量處理節點。在大部分情況下,跳躍表的效率和平衡樹是一樣的,但是邏輯上比平衡樹更加簡單。redis通過跳躍表實現有序集合鍵的底層實現之一。...