向内存中连续存入数据_内存节省到极致!Redis中这个数据结构,值得每个程序员了解...
在之前我們介紹了,Redis有五種基礎(chǔ)數(shù)據(jù)類型,分別是String,Set,List,Hash與SortSet。
今天我們又學(xué)習(xí)了一個(gè)命令,我們可以使用DEBUG OBJECT key查詢Redis中,存儲(chǔ)數(shù)據(jù)的一些關(guān)鍵信息,如下所示:
我們發(fā)現(xiàn)了ziplist跟intset這兩種不在上述基礎(chǔ)類型的數(shù)據(jù)結(jié)構(gòu),這又是什么呢?
Redis為了節(jié)省內(nèi)存空間,當(dāng)Hash與Zset元素個(gè)數(shù)較少的時(shí)候,會(huì)使用ziplist進(jìn)行存儲(chǔ),也就是壓縮表。在壓縮表中,元素緊密排列,更加節(jié)省內(nèi)存。今天,我們一起來(lái)探討ziplist的內(nèi)部,看一看ziplist的實(shí)現(xiàn)。
- 數(shù)據(jù)結(jié)構(gòu)Zlist是有上述元素構(gòu)成:zlbytes 記錄著整一個(gè)壓縮表的長(zhǎng)度
- zltail 記錄著最后一個(gè)元素的偏移量,這是為了倒序遍歷整個(gè)zlist
- zlen 用來(lái)記錄壓縮表中節(jié)點(diǎn)的數(shù)量
- entryX 列表中的節(jié)點(diǎn),節(jié)點(diǎn)用來(lái)存儲(chǔ)具體的數(shù)據(jù),廠部補(bǔ)丁。
- zlend 一個(gè)特殊值0XFF,用來(lái)標(biāo)記壓縮列表已經(jīng)結(jié)束了。
我們注意到,在Redis中,數(shù)據(jù)結(jié)構(gòu)壓縮表是緊湊排列的,所以,我們每次查詢都需要遍歷整一個(gè)列表,才能查詢到相關(guān)數(shù)據(jù),因?yàn)閦iplist存放的個(gè)數(shù)非常有限,所以性能的開(kāi)銷并不大。
接下來(lái),我們來(lái)看一看Redis的壓縮表中,節(jié)點(diǎn)的構(gòu)成。
- prevlen 用來(lái)記錄上一個(gè)節(jié)點(diǎn)的長(zhǎng)度,因?yàn)閴嚎s表可能需要倒序遍歷,所以需要記錄prevlen才能夠定位出上一個(gè)entry的位置。
- encoding 在Redis的壓縮表中,設(shè)計(jì)精髓都在這里,為了節(jié)省壓縮表占用的內(nèi)存,Redis對(duì)Encoding進(jìn)行了極致的設(shè)計(jì)。一般都是讀取前8個(gè)字節(jié),用來(lái)判斷存儲(chǔ)的數(shù)據(jù)是什么。舉個(gè)簡(jiǎn)單的例子,如果前8個(gè)字節(jié)是00xxxxxx,這里的00開(kāi)頭,表示的是這是個(gè)非常短的字符串,后面的6個(gè)x表示字符串的長(zhǎng)度,2^6-1等于63,所以,這個(gè)數(shù)據(jù)就encoding就表示,content是一個(gè)非常短的字符串,長(zhǎng)度最多為63位。另一個(gè)例子,如果前8個(gè)字節(jié)是11111110,那么這個(gè)表示是int8,后面跟一個(gè)字節(jié)用來(lái)表示整數(shù)。
- content 用來(lái)存放具體的數(shù)據(jù),前面已經(jīng)提到了,是用來(lái)存放具體的數(shù)據(jù)。
根據(jù)上述規(guī)則,假如我們存放的數(shù)據(jù)是"hello world",那么Redis用來(lái)保存這個(gè)數(shù)據(jù)Entry如下所示,prevlen用來(lái)保存上一個(gè)Entry的長(zhǎng)度,跟本數(shù)據(jù)無(wú)關(guān),因?yàn)槭切∽址?#xff0c;所以encoding為00001011,1011表示長(zhǎng)度為11,content則為長(zhǎng)度為11的字符串helloworld。
最后,我們?cè)賮?lái)了解下連鎖更新,如同數(shù)據(jù)結(jié)構(gòu)中數(shù)組插入元素時(shí)間復(fù)雜度為O(N)一樣,在Redis的數(shù)據(jù)結(jié)構(gòu)壓縮表中,插入數(shù)據(jù)也會(huì)一樣,并且插入數(shù)據(jù)還可能會(huì)引起連鎖更新,因?yàn)槊總€(gè)Entry都會(huì)記錄上一個(gè)Entry的長(zhǎng)度,所以,在插入一定數(shù)量的Entry之后,Redis就會(huì)使用其他數(shù)據(jù)結(jié)構(gòu)進(jìn)行數(shù)據(jù)的存儲(chǔ)。
好了,有關(guān)Redis壓縮表我們就介紹到這里。歡迎大家關(guān)注我,近期還準(zhǔn)備了一些AI相關(guān)的知識(shí),整理后會(huì)和大家繼續(xù)分享。大家的支持是我繼續(xù)嘮嗑的動(dòng)力。同名公眾號(hào)(沙茶敏碎碎念)
總結(jié)
以上是生活随笔為你收集整理的向内存中连续存入数据_内存节省到极致!Redis中这个数据结构,值得每个程序员了解...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 270 扩展固态硬盘_游戏人的扩展坞应该
- 下一篇: python 查询sqlserver 视