《Redis設計與實現》1.數據結構域對象

一、SDS:simple dynamic string
  • int len:已使用的buf長度
  • int free:未使用的長度
  • char buf[]:存儲字符串
二、鏈表:雙向鏈表,包含head、tail指針,head的prev爲null,tail節點的next爲null
三、字典:類似於java hashmap,rehash過程是漸進式的,內部維護一個是否正在rehash的標識,維護一個rehash
四、跳躍表
  • header頭結點
  • tail尾結點
  • level跳躍表最大節點層數
  • length跳躍表長度
        每個節點隨機層高,並保存score分值,backward後退指針,obj存儲對象。
  • score分值,跳躍表按照score排序。如下圖從2—>5—>6
  • backward後退指針,第二個節點指向第一個節點,第一個幾點指向NULL
  • obj爲實際存儲的內容
  • 層,每個層包含前進指針與跨度
  • 前進指針指向右方的節點
  • 跨度是跳躍幾個節點
 
跳躍表查找:
如上如,要找到o2:
  1. 找到頭結點,第一個前進指針不爲空的層L4(可直接從跳躍表信息level中獲取)
  2. 比對L4指針節點與o2的大小,o3>o2,則降層到L3
  3. 判斷頭結點的L3前進指針節點與o2的大小,o2>o1,跳躍到前進指針節點
  4. 判斷o1的L3前進指針節點,o2 = o2,找到節點
 
插入:例如插入ox,score爲3
  1. 用查找發找到ox的位置,也就是在o1之後
  2. 隨機爲ox增加層高,從L1開始,將其與o1相連,待隨機層高超過o1,則向前遍歷節點,找到存在同層的節點直到header(xNode),然後新節點的同層指xNode該層的前進指針,將xNode的前進指針指向該新節點。
 
五、整數集合
  • encoding保存整數的位數,16、32、64
  • length元素個數
  • contents數組內容
升級:當在16位的整數數組中,insert一個32位的數字,則需要升級
  1. 分配空間,先分配足夠的空間,然後將新進來的數字放到對的位置上
  2. 然後將原本的數字倒着放置到對應的位置上
如下往16位的數組中插入60000
六、壓縮列表
 
七、對象
屬性:type、encoding、ptr、refcount、lru
type:REDIS_STRING字符串對象、REDIS_LIST列表對象、REDIS_HASH哈希對象、REDIS_SET集合對象、REDIS_ZSET有序集合對象
 
1.字符串對象
編碼格式:int、raw、embstr
大於32字節,使用SDS保存,編碼設置爲raw;小於32字節,也是用SDS保存,編碼格式embstr
  • raw需要分配2次內存,分別是redisObject與sds。
  • embstr分配一次內存,直接包含redisObject與SDS,是連續的。
embstr比raw的優勢:
  • embstr需要分配一次內存,而raw需要兩次
  • embstr只需要釋放一次內存,而raw需要兩次
  • embstr的redisObject與SDS存儲在連續的空間裏,可以更好利用緩存
 
2.列表對象
編碼格式:ziplist、linkedlist(雙端鏈表)
ziplist條件,必須同時滿足:
  1. 列表字符串長度都小於64字節(list-max-ziplist-value)
  2. 列表元素數量小於512(list-max-ziplist-entries)
 
3.哈希對象
編碼格式:ziplist、hashtable
ziplist條件同上。
 
4.集合對象
編碼格式:intset、hashtable
intset條件,都爲整數,且不超過512
 
5.有序集合對象
編碼格式:ziplist、skiplist
實際是字典dict與跳躍表zsl都保存了一份,保留了查找的O(1),也保留了範圍O(logN)。
 
DEL、EXPIRE、RENAME、TYPE、OBJECT:可適用於任何key;
SET、GET、APPEND、STRLEN:只能用於字符串鍵;
HDEL、HSET、HGET、HLEN:只能用於哈希鍵;
RPUSH、LPOP、LINSERT、LLEN:只能用於列表鍵;
SADD、SPOP、SINSERT、SCARD:只能用於集合鍵;
ZADD、ZCARD、ZRANK、ZSCORE:只能用於有序集合鍵;
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章