redis數(shù)據(jù)結(jié)構(gòu)上層--對(duì)象系統(tǒng)

? ? redis沒(méi)有直接使用數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)鍵值對(duì)的數(shù)據(jù)庫(kù)辫封,而是基于這些數(shù)據(jù)結(jié)構(gòu)創(chuàng)建了一個(gè)對(duì)象系統(tǒng)厉熟,包含字符串對(duì)象、列表對(duì)象溉潭、哈希對(duì)象、集合對(duì)象和有序集合對(duì)象五種類型少欺。

? ? 對(duì)redis數(shù)據(jù)庫(kù)鍵值對(duì)來(lái)說(shuō)喳瓣,鍵永遠(yuǎn)都是字符串對(duì)象,而值可以 是字符串對(duì)象赞别、列表對(duì)象畏陕、哈希對(duì)象、集合對(duì)象和有序集合對(duì)象五種類型仿滔,故接下來(lái)所說(shuō)的幾種對(duì)象惠毁,都是鍵值對(duì)的值對(duì)象。

type: 對(duì)象類型崎页,五種類型之一鞠绰。

encoding:對(duì)象所使用的編碼,也即對(duì)象使用了什么數(shù)據(jù)結(jié)構(gòu)作為底層實(shí)現(xiàn)飒焦。


每種類型的對(duì)象都至少使用了兩種不同編碼(數(shù)據(jù)結(jié)構(gòu))蜈膨。

字符串對(duì)象:

? ? ? ? 整數(shù)值屿笼、embstr、簡(jiǎn)單動(dòng)態(tài)字符串

列表對(duì)象:

? ? ? ? 壓縮列表翁巍、雙端列表

哈希對(duì)象:

? ? ? ? 壓縮列表驴一、字典實(shí)現(xiàn)

集合對(duì)象:

? ? ? ? 整數(shù)集合、字典實(shí)現(xiàn)

有序集合對(duì)象:

? ? ? ? 壓縮列表實(shí)現(xiàn)灶壶、跳躍表和字典實(shí)現(xiàn)


一 字符串對(duì)象

? ? 字符串對(duì)象保存的是整數(shù)值肝断,且可以用long表示,值會(huì)保存在pre屬性里驰凛,并將字符串對(duì)象的編碼設(shè)置為int胸懈。

? ? 字符串對(duì)象是唯一一種會(huì)被其他四種對(duì)象嵌套的對(duì)象。

? ? 字符串對(duì)象保存的是字符串值洒嗤,且值的長(zhǎng)度大于32字節(jié)箫荡,則以SDS來(lái)保存這個(gè)字符串值,并將對(duì)象編碼設(shè)置為raw渔隶。

? ???字符串對(duì)象保存的是字符串值羔挡,且值的長(zhǎng)度小于等于32字節(jié),則以SDS來(lái)保存這個(gè)字符串值间唉,并將對(duì)象編碼設(shè)置為embstr绞灼。

? ? raw和embstr的區(qū)別在于,raw會(huì)調(diào)用兩次內(nèi)存分配來(lái)分別創(chuàng)建redisObject結(jié)構(gòu)和sdshdr結(jié)構(gòu)呈野,而embstr則只調(diào)用一次內(nèi)存分配函數(shù)來(lái)分配一塊連續(xù)的空間低矮。同理,釋放對(duì)象內(nèi)存的時(shí)候被冒,raw需要調(diào)用兩次军掂,而embstr只需調(diào)用一次。

? ? embstr編碼的字符串對(duì)象在執(zhí)行命令時(shí)昨悼,效果和raw編碼字符串對(duì)象效果一樣蝗锥。

? ? embstr編碼字符串對(duì)象只讀,一旦修改率触,則會(huì)變?yōu)閞aw編碼字符串终议。

二 列表對(duì)象

列表對(duì)象的編碼是ziplist或linkedlist。

ziplist編碼的列表對(duì)象使用壓縮列表作為底層實(shí)現(xiàn)葱蝗,每個(gè)壓縮列表節(jié)點(diǎn)保存了一個(gè)列表元素穴张。

linkedlist編碼的列表對(duì)象使用雙端鏈表作為底層實(shí)現(xiàn),每個(gè)雙端鏈表節(jié)點(diǎn)都保存了一個(gè)字符串對(duì)象两曼,而每個(gè)字符串對(duì)象都保存了一個(gè)列表元素皂甘。

為了簡(jiǎn)化字符串對(duì)象表示,實(shí)際StringObject的結(jié)構(gòu)如下圖:

StringObject

列表對(duì)象在壓縮列表和雙端鏈表間的轉(zhuǎn)換:

1,列表對(duì)象保存的所有字符串元素的長(zhǎng)度都小于64字節(jié)悼凑。

2叮贩,列表對(duì)象保存的元素?cái)?shù)量小于512個(gè)击狮。

滿足上述兩個(gè)條件,列表對(duì)象使用ziplist編碼,否則使用linkedlist編碼。

注:以上兩個(gè)條件的上限可配置修改朦佩,list-max-ziplist-value 和 list-max-ziplist-entries 。

三 哈希對(duì)象

哈希對(duì)象的編碼可以是ziplist 或 hashtable 档冬。

ziplist編碼的哈希對(duì)象使用壓縮列表作為底層實(shí)現(xiàn),有新鍵值對(duì)(指值是鍵值對(duì)形式)進(jìn)入時(shí)桃纯,先把保存了鍵的壓縮列表節(jié)點(diǎn)放到壓縮列表表尾酷誓,然后再把保存了值的壓縮列表節(jié)點(diǎn)放到壓縮列表表尾,故同一鍵值對(duì)的兩個(gè)節(jié)點(diǎn)總是連在一起态坦。


hashtable編碼的哈希對(duì)象使用字典作為底層實(shí)現(xiàn)盐数,哈希對(duì)象中的每個(gè)鍵值對(duì)都使用一個(gè)字典鍵值對(duì)來(lái)保存。

哈希對(duì)象兩種編碼間的轉(zhuǎn)換:

1伞梯,哈希對(duì)象所保存的所有鍵值對(duì)的鍵和值的字符串長(zhǎng)度都小于64字節(jié)玫氢。

2,哈希對(duì)象的鍵值對(duì)的數(shù)量小于512個(gè)谜诫。

滿足上述兩個(gè)條件漾峡,哈希對(duì)象使用ziplist編碼,否則使用hashtable編碼喻旷。

注:以上兩個(gè)條件的上限可配置修改生逸,hash-max-ziplist-value 和 hash-max-ziplist-entries 。

四 集合對(duì)象

集合對(duì)象編碼可以用intset 或者 hashtable 且预。

intset編碼的集合對(duì)象使用整數(shù)集合作為底層實(shí)現(xiàn)槽袄,集合對(duì)象的所有元素都被保存在整數(shù)集合里。

hashtable編碼的集合對(duì)象使用字段作為底層實(shí)現(xiàn)锋谐,字典的每一個(gè)鍵都是字符串對(duì)象掰伸,每個(gè)字符串對(duì)象包含了一個(gè)集合元素,而字典的值全部被置為null 怀估。

intset編碼
hashtable編碼

集合對(duì)象兩種編碼間轉(zhuǎn)換:

1,集合對(duì)象保存的所有元素都是整數(shù)值 合搅。

2多搀,集合對(duì)象保存的元素個(gè)數(shù)不超過(guò)512 。

滿足上述條件灾部,則使用intset編碼康铭,否則,使用hashtable編碼 赌髓。

注:以上第二個(gè)條件的上限可配置修改从藤, set-max-intset-entries 催跪。

五 有序集合對(duì)象

有序集合的編碼可以用ziplist 或 skiplist 。

ziplist編碼的有序集合對(duì)象使用壓縮列表作為底層實(shí)現(xiàn)夷野,每個(gè)集合元素使用 兩個(gè)緊挨在一起的壓縮列表節(jié)點(diǎn)保存懊蒸,第一個(gè)節(jié)點(diǎn)保存元素成員(member),第二個(gè)節(jié)點(diǎn)保存元素的分值(score)悯搔。

壓縮列表內(nèi)的集合元素按分值從小到大排序骑丸,分值小的元素靠近表頭,分值大的靠近表尾妒貌。

skiplist 編碼的有序集合對(duì)象使用zset結(jié)構(gòu)作為底層實(shí)現(xiàn)通危,一個(gè)zset結(jié)構(gòu)同時(shí)包含一個(gè)字典和一個(gè)跳躍表。

zset結(jié)構(gòu)中的zs1跳躍表按分值從小到大保存所有集合元素灌曙,每個(gè)跳躍表節(jié)點(diǎn)都保存了一個(gè)集合元素菊碟,跳躍表節(jié)點(diǎn)的object屬性保存了元素成員,而跳躍表節(jié)點(diǎn)的score屬性則保存了元素的分值在刺。

zset結(jié)構(gòu)中的dict字典為有序集合創(chuàng)建了一個(gè)從成員到分值的映射逆害,字典匯中的每個(gè)鍵值對(duì)都保存了一個(gè)集合元素,字典的鍵保存了元素的成員增炭,字典的值保存了元素的分值忍燥。

理論上,有序集合可以單獨(dú)使用字典或跳躍表一種數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)隙姿,但無(wú)論單獨(dú)用哪種梅垄,性能上總是比不上同時(shí)使用。比如查找指定成員分值输玷,直接使用dict队丝,而查找成員排名,則使用跳躍表欲鹏。

有序集合ziplist和zset編碼間的轉(zhuǎn)換:

1机久,有序集合保存的元素?cái)?shù)量小于128個(gè)。

2赔嚎,有序集合保存的所有元素成員長(zhǎng)度小于64字節(jié)膘盖。

滿足上述兩個(gè)條件,則使用ziplist 尤误,否則侠畔,使用zset 。

注:以上兩個(gè)條件的上限可配置修改损晤,zset-max-ziplist-value 和 zset-max-ziplist-entries 软棺。

五 內(nèi)存收回

因C語(yǔ)言沒(méi)有自動(dòng)內(nèi)存收回功能,所以redis自己構(gòu)建了一個(gè)引用計(jì)數(shù)技術(shù)實(shí)現(xiàn)內(nèi)存回收機(jī)制尤勋。

1喘落,創(chuàng)建一個(gè)新對(duì)象時(shí)茵宪,引用計(jì)數(shù)的值被初始化為1;

2瘦棋,當(dāng)對(duì)象被一個(gè)新程序使用時(shí)稀火,它的引用計(jì)數(shù)增加1;

3兽狭,當(dāng)對(duì)象不再被一個(gè)程序使用時(shí)憾股,它的引用計(jì)數(shù)減1;

4箕慧,當(dāng)對(duì)象的引用計(jì)數(shù)值變?yōu)?時(shí)服球,對(duì)象所占用的內(nèi)存會(huì)被釋放。

六 對(duì)象共存

對(duì)象引用計(jì)數(shù)的屬性還帶有對(duì)象共存的作用颠焦。

redis中斩熊,多個(gè)鍵共享同一個(gè)值時(shí),數(shù)據(jù)庫(kù)鍵的值指針指向一個(gè)現(xiàn)有的值對(duì)象伐庭,同時(shí)被共享的值對(duì)象的引用計(jì)數(shù)增一粉渠。

目前來(lái)說(shuō),redis初始化服務(wù)器時(shí)圾另,會(huì)創(chuàng)建一萬(wàn)個(gè)字符串對(duì)象霸株,包含從0-9999所有整數(shù)值,所以當(dāng)用到0-9999的字符串對(duì)象時(shí)集乔,服務(wù)器會(huì)共享這些對(duì)象去件,而不會(huì)再創(chuàng)建新對(duì)象。

七 對(duì)象的空轉(zhuǎn)時(shí)長(zhǎng)

lru:記錄了對(duì)象最后一次被命令程序訪問(wèn)的時(shí)間扰路。

redisObject 完整結(jié)構(gòu):





參考文獻(xiàn)《redis設(shè)計(jì)與實(shí)現(xiàn)第二版》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末尤溜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子汗唱,更是在濱河造成了極大的恐慌宫莱,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哩罪,死亡現(xiàn)場(chǎng)離奇詭異授霸,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)际插,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門碘耳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人腹鹉,你說(shuō)我怎么就攤上這事》蠊瑁” “怎么了功咒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵愉阎,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我力奋,道長(zhǎng)榜旦,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任景殷,我火速辦了婚禮溅呢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘猿挚。我一直安慰自己咐旧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布绩蜻。 她就那樣靜靜地躺著铣墨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪办绝。 梳的紋絲不亂的頭發(fā)上伊约,一...
    開(kāi)封第一講書(shū)人閱讀 51,573評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音孕蝉,去河邊找鬼屡律。 笑死,一個(gè)胖子當(dāng)著我的面吹牛降淮,可吹牛的內(nèi)容都是我干的超埋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼骤肛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼纳本!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起腋颠,我...
    開(kāi)封第一講書(shū)人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤繁成,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后淑玫,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體巾腕,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年絮蒿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了尊搬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡土涝,死狀恐怖佛寿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤冀泻,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布常侣,位于F島的核電站,受9級(jí)特大地震影響弹渔,放射性物質(zhì)發(fā)生泄漏胳施。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一肢专、第九天 我趴在偏房一處隱蔽的房頂上張望舞肆。 院中可真熱鬧,春花似錦博杖、人聲如沸椿胯。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)压状。三九已至,卻和暖如春跟继,著一層夾襖步出監(jiān)牢的瞬間种冬,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工舔糖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留娱两,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓金吗,卻偏偏與公主長(zhǎng)得像十兢,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子摇庙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355