redis: 數(shù)據(jù)類型

Redis實現(xiàn)數(shù)據(jù)庫key:value存儲時夺鲜,基于基本數(shù)據(jù)結(jié)構(gòu)創(chuàng)建了一個對象系統(tǒng)镰踏,該系統(tǒng)包含了string, list, hash, set, zset五種類型的對象,每種都由redisObject表示当犯,type表示了對象的類型征椒,encoding表示對象的編碼方式,ptr指針指向了底層相應的基礎數(shù)據(jù)結(jié)構(gòu)末荐。

typedef struct redisObject {
    //類型
    unsigned type:4;
    unsigned notused:2; 
    //編碼
    unsigned encoding:4;
    unsigned lru:22; 
    //引用計數(shù)
    int refcount;
    //指向底層實現(xiàn)數(shù)據(jù)結(jié)構(gòu)的指針
    void *ptr;
} robj;
type

encoding

1.string

string的類型為REDIS_STRING常量,編碼有int, raw和embstr三種方式侧纯。

1.1. int

若一個字符串保存的是整數(shù)值而且可以用long類型表示,那么對象的ptr屬性將存放整數(shù)值(將void * 轉(zhuǎn)為long)甲脏, 同時將encoding設為int


int

1.2. raw

若字符串對象要保存長度大于32字節(jié)的字符串值眶熬,那么將使用SDS保存該這個值,同時將encoding設置為raw


raw

1.3. embstr

embstr是用于保存短字符串的優(yōu)化編碼方式块请,雖然同樣使用SDS保存字符串值娜氏,但是僅調(diào)用一次內(nèi)存分配函數(shù),分配一塊連續(xù)的內(nèi)存空間給redisObject和SDS墩新。


embstr

2.list

list的類型為REDIS_LIST常量贸弥,編碼可以是ziplist和linkedlist

1. ziplist

使用壓縮列表作為底層實現(xiàn),每個entry保存一個元素

redis> RPUSH numbers 1 "three" 5
(integer 3)
numbers列表

2. linkedlist

使用雙向鏈表作為實現(xiàn)抖棘, 每個節(jié)點保存一個字符串對象茂腥,字符串對象保存一個列表元素狸涌。


3.編碼轉(zhuǎn)換

同時滿足以下條件可使用ziplist,否則使用linkedlist

  1. 所有元素字節(jié)數(shù)少于64
  2. 列表元素數(shù)量少于512

3. hash對象

hash的類型為REDIS_HASH常量最岗,編碼可以是ziplist和hashtable

1. ziplist

redis> HSET  x name "Tom"
(integer) 1
redis> HSET  x age 25
// ...
redis> HSET  x career "Programmer"
// ...

每次在加入一對新的key:value時帕胆,先將key push到列表尾端,再將value push到列表尾端般渡。



2. hashtable

底層使用字典實現(xiàn),key 和 value 都是 字符串對象懒豹, 對象使用相應編碼保存字符串的值


3.編碼轉(zhuǎn)換

滿足以下情況時,可以將hashtable編碼轉(zhuǎn)為ziplist編碼驯用,否則都需要使用hashtable:

  • 鍵值對數(shù)量小于512個
  • 鍵脸秽、值的字符串長度都小于64字節(jié)

4. set

類型為REDIS_SET, 編碼可以是intset和hashtable

1. intset

intset底層使用整數(shù)集合保存集合對象的元素蝴乔。


2. hashtable

hashtable類型的集合底層使用字典實現(xiàn)记餐,其中字典的key使用字符串對象保存元素值,value為空薇正。


3. 編碼轉(zhuǎn)換

同時滿足以下兩個條件是片酝,可以使用intset編碼
1. 所有元素都是整數(shù)值
2. 元素數(shù)量少于512

5. zset

類型為REDIS_ZSET, 編碼可以為ziplist和skiplist

5.1ziplist

壓縮列表內(nèi)挖腰,使用相連的兩個壓縮列表節(jié)點分別存儲member和score雕沿;元素按score排序,大的靠近表位猴仑,小的靠近表頭审轮。


redis> ZADD price 8.5 apple 5.0 banana 6.5 cherry

添加三個元素后ziplist如圖


5.2 skiplist

skiplist編碼底層使用zset實現(xiàn)

typedef struct zset{
    zskiplist *zsl;
    dict *dict; 
}
5.2.1zsl

zsl跳躍表按score從小到大保存所有元素,每個跳躍表節(jié)點保存一個元素.其中ele和score分別表示元素的成員和分值辽俗。

  typedef struct zskiplistNode {
      /* redis3.0版本中使用robj類型表示疾渣,但是在redis4.0.1中直接使用sds類型表示 */
      sds ele;
      double score;
      struct zskiplistNode *backward;
      /** 這里該成員是一種柔性數(shù)組,只是起到了占位符的作用,在sizeof(struct zskiplistNode)的時候根本就不占空間,這和sdshdr結(jié)構(gòu)的定義是類似的(sds.  h文件)榆苞; 如果想要分配一個struct zskiplistNode大小的空間稳衬,那么應該的分配的大小為sizeof(struct zskiplistNode) + sizeof(struct zskiplistLevel) *   count)。其中count為柔性數(shù)組中的元素的數(shù)量
       **/
      struct zskiplistLevel {
          /* 對應level的下一個節(jié)點 */
          struct zskiplistNode *forward;
          /* 從當前節(jié)點到下一個節(jié)點的跨度 */
          unsigned int span;
      } level[];
  } zskiplistNode;

通過跳躍表坐漏,可以高效實現(xiàn)范圍型操作薄疚,如ZRANGE, ZRANK赊琳。

5.2.2dict

dict提供了成員到score的映射街夭,因此可以高效的查找某個成員的score。
dict與zsl共享成員和score躏筏,因此內(nèi)存開銷并不大

3.編碼轉(zhuǎn)換:

同時滿足以下條件時板丽,使用ziplist,否則轉(zhuǎn)skiplist

  1. 元素數(shù)量少于128
  2. 所有元素成員字節(jié)數(shù)都少于64字節(jié)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市埃碱,隨后出現(xiàn)的幾起案子猖辫,更是在濱河造成了極大的恐慌,老刑警劉巖砚殿,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啃憎,死亡現(xiàn)場離奇詭異,居然都是意外死亡似炎,警方通過查閱死者的電腦和手機辛萍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羡藐,“玉大人贩毕,你說我怎么就攤上這事∑袜拢” “怎么了辉阶?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瘩扼。 經(jīng)常有香客問我睛藻,道長,這世上最難降的妖魔是什么邢隧? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮冈在,結(jié)果婚禮上倒慧,老公的妹妹穿的比我還像新娘。我一直安慰自己包券,他們只是感情好纫谅,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著溅固,像睡著了一般付秕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侍郭,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天询吴,我揣著相機與錄音,去河邊找鬼亮元。 笑死猛计,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的爆捞。 我是一名探鬼主播奉瘤,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼煮甥!你這毒婦竟也來了盗温?” 一聲冷哼從身側(cè)響起藕赞,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卖局,沒想到半個月后斧蜕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡吼驶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年惩激,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蟹演。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡风钻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酒请,到底是詐尸還是另有隱情骡技,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布羞反,位于F島的核電站布朦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏昼窗。R本人自食惡果不足惜是趴,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望澄惊。 院中可真熱鬧唆途,春花似錦、人聲如沸掸驱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毕贼。三九已至温赔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鬼癣,已是汗流浹背陶贼。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留待秃,地道東北人骇窍。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像锥余,于是被迫代替她去往敵國和親腹纳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容