Redis學習筆記(六) 對象

前面咱們看了Redis用到的主要數據結構,如簡單動態字符串(SDS)、雙向鏈表、字典、壓縮列表、整數集合等。redis

可是Redis並無直接使用這些數據結構來實現鍵值對,而是基於這些數據結構建立了一個對象系統,這個系統包括字符串對象、列表對象、哈希對象、集合對象、有序集合對象,除此以外,redis的對象系統還實現了基於計數技術的內存回收機制,另外redis還經過引用計數技術實現了對象共享機制(適當條件下,多個數據庫鍵共享同一個對象來節約內存)。數據庫

最後,redis的對象帶有訪問時間記錄信息,該信息能夠用於計算數據庫鍵的空轉時長,在服務器啓用了maxmemory功能的狀況下,空轉時長較大的鍵會優先被服務器刪除。服務器

 

一、Redis中的每一個結構都是由redisObject結構標識,包含ptr(指向底層實現的數據結構)、encoding(決定用那種底層數據結構)、type等屬性。數據結構

 

二、當咱們建立一個鍵值對時,咱們至少會建立兩個對象:鍵對象(字符串對象),值對象(物種類型)。函數

 

三、字符串對象的編碼能夠是整數、raw或者enbstr、sds學習

  1. enbstr(短字符串長度小於32)調用一次分配內存函數,分配一個連續的內存包含redisObject結構與sdshdr結構,不包含修改命令,執行任何修改命令會轉爲raw對象。編碼

  2. sds(字符串長度超過32)。spa

  3. raw 會調用兩次內存分配分別建立redisObject結構與sdshdr結構。設計

 

四、列表對象,列表對象的編碼能夠是ziplist或者linkedlistcode

  1. ziplist使用壓縮列表做爲底層實現。列表對象保存的全部字符串元素長度都小於64字節,元素數量小於512個時使用壓縮列表作爲底層實現。

  2. linkedlist編碼列表對象使用雙向鏈表做爲底層實現,每一個雙向鏈表節點都保存一個字符串對象。

 

五、哈希對象

  1. 哈希對象的編碼能夠是ziplist或者hashtable

  2. ziplist編碼的哈希對象使用壓縮表做爲底層實現,當由新的鍵值對加入到hash對象時,程序會先將保存了鍵的壓縮列表節點推入到壓縮列表的表尾,而後將保存了值的壓縮列表節點推入到壓縮列表的表尾。

  3. 使用hashtable做爲編碼的哈希對象使用字典做爲底層實現,鍵使用字符串對象,值使用字符串對象。

六、集合對象

  1. 集合對象的編碼能夠是 intset或者是hashtable

  2. intset編碼的集合對象使用整數集合做爲底層實現。

  3. hashtable編碼的集合對象使用字典做爲底層實現,字典的每一個鍵都是一個字符串對象,每一個字符串對象包含一個集合元素,而字段的值則所有設置爲null。

     

     

  4. 對象轉換 。intset轉hashtable條件:元素中不全是整數或者元素數量超過512.

 

七、有序集合對象

  1. 有序集合的編碼能夠是ziplist 或者skiplist

  2. ziplist編碼的壓縮列表對象使用壓縮列表做爲底層實現,每一個集合元素使用兩個挨在一塊兒的壓縮列表節點來保存,第一個節點保存元素的成員(member)第二個元素則保存元素的分值(score)。

  3. skiplist編碼的有序集合對象使用zset結構做爲底層實現,一個zset結構同時包含一個字典和一個跳躍表。

  4. typedef struct zset{
        zskiplist *zsl;
        dict *dict;//保存從成員到分值的映射,鍵保存元素成員 值保存了分數。
    }

     

  5. 解釋下爲何同時使用字典與跳躍表來實現有序集合:雖然用兩種結構的任意一種都能實現有序集合,可是當咱們只是用字典來實現有序集合時,因爲字典是一個無序的保存元素,當咱們實行範圍操做時,須要先對全部的元素進行排序,這裏所使用的時間複雜度至少爲O(NlogN),而且有額外的內存消費;另外若是隻使用跳躍表來實現有序集合時,雖然範圍操做的優點被保留,可是沒有了字典根據成員查找分值時這一操做的複雜度將從O(1)提高到O(logN)。

  6. 編碼轉換,當元素的數量小於128,且每一個元素的長度都小於64字節時,使用ziplist。

八、內存回收

  1. 每一個對象的引用技術信息由redisObject結構的refcount屬性記錄。

  2. 建立對象時,計數值會被默認初始化爲1,被程序使用時,計數器加一,再也不被使用時,計數器減一,當計數器爲0時,對象佔用的內存會被釋放。

 

九、對象空轉時長

  1. 對象空轉時長使用redisObjet結構中的lru屬性記錄,該屬性記錄對象最後一次被訪問的時間。

 

--------- end --------

 

天天學一點,總會有收穫。

 

說明:尊重做者知識產權,文中內容參考《Redis設計與實現》,僅在此作學習與你們分享。

 

相關文章
相關標籤/搜索