1、降低redis內(nèi)存占用的優(yōu)點(diǎn)
1、有助于減少創(chuàng)建快照和加載快照所用的時(shí)間
2、提升載入AOF文件和重寫(xiě)AOF文件時(shí)的效率
3、縮短從服務(wù)器進(jìn)行同步所需的時(shí)間
4、無(wú)需添加額外的硬件就可以讓redis存貯更多的數(shù)據(jù)
2、短結(jié)構(gòu)
Redis為列表、集合、散列、有序集合提供了一組配置選項(xiàng),這些選項(xiàng)可以讓redis以更節(jié)約的方式存儲(chǔ)較短的結(jié)構(gòu)。
2.1、ziplist壓縮列表(列表、散列、有續(xù)集和)
通常情況下使用的存儲(chǔ)方式
當(dāng)列表、散列、有序集合的長(zhǎng)度較短或者體積較小的時(shí)候,redis將會(huì)采用一種名為ziplist的緊湊存儲(chǔ)方式來(lái)存儲(chǔ)這些結(jié)構(gòu)。
ziplist是列表、散列、有序集合這三種不同類型的對(duì)象的一種非結(jié)構(gòu)化表示,它會(huì)以序列化的方式存儲(chǔ)數(shù)據(jù),這些序列化的數(shù)據(jù)每次被讀取的時(shí)候都需要進(jìn)行解碼,每次寫(xiě)入的時(shí)候也要進(jìn)行編碼。
雙向列表與壓縮列表的區(qū)別:
為了了解壓縮列表比其他數(shù)據(jù)結(jié)構(gòu)更加節(jié)約內(nèi)存,我們以列表結(jié)構(gòu)為例進(jìn)行深入研究。
典型的雙向列表
在典型雙向列表里面,每個(gè)值都都會(huì)有一個(gè)節(jié)點(diǎn)表示。每個(gè)節(jié)點(diǎn)都會(huì)帶有指向鏈表前一個(gè)節(jié)點(diǎn)和后一個(gè)節(jié)點(diǎn)的指針,以及一個(gè)指向節(jié)點(diǎn)包含的字符串值的指針。
每個(gè)節(jié)點(diǎn)包含的字符串值都會(huì)分為三部分進(jìn)行存儲(chǔ)。包括字符串長(zhǎng)度、字符串值中剩余可用字節(jié)數(shù)量、以空字符結(jié)尾的字符串本身。
例子:
假若一個(gè)某個(gè)節(jié)點(diǎn)存儲(chǔ)了'abc'字符串,在32位的平臺(tái)下保守估計(jì)需要21個(gè)字節(jié)的額外開(kāi)銷(三個(gè)指針+兩個(gè)int+空字符即:3*4+2*4+1=21)
由例子可知存儲(chǔ)一個(gè)3字節(jié)字符串就需要付出至少21個(gè)字節(jié)的額外開(kāi)銷。
ziplist
壓縮列表是由節(jié)點(diǎn)組成的序列,每個(gè)節(jié)點(diǎn)包含兩個(gè)長(zhǎng)度和一個(gè)字符串。第一個(gè)長(zhǎng)度記錄前一個(gè)節(jié)點(diǎn)的長(zhǎng)度(用于對(duì)壓縮列表從后向前遍歷);第二個(gè)長(zhǎng)度是記錄本當(dāng)前點(diǎn)的長(zhǎng)度;被存儲(chǔ)的字符串。
例子:
存儲(chǔ)字符串'abc',兩個(gè)長(zhǎng)度都可以用1字節(jié)來(lái)存儲(chǔ),因此所帶來(lái)的額外開(kāi)銷為2字節(jié)(兩個(gè)長(zhǎng)度即1+1=2)
結(jié)論:
壓縮列表是通過(guò)避免存儲(chǔ)額外的指針和元數(shù)據(jù),從而達(dá)到降低額外的開(kāi)銷。
配置:
#list list-max-ziplist-entries 512 #表示允許包含的最大元素?cái)?shù)量 list-max-ziplist-value 64 #表示壓縮節(jié)點(diǎn)允許存儲(chǔ)的最大體積 #hash #當(dāng)超過(guò)任一限制后,將不會(huì)使用ziplist方式進(jìn)行存儲(chǔ) hash-max-ziplist-entries 512 hash-max-ziplist-value 64 #zset zset-max-ziplist-entries 128 zset-max-ziplist-value 64
測(cè)試list:
1、建立test.php文件
#test.php <?php $redis=new Redis(); $redis->connect('192.168.95.11','6379'); for ($i=0; $i<512 ; $i++) { $redis->lpush('test-list',$i.'-test-list'); #往test-list推入512條數(shù)據(jù) } ?>
此時(shí)的test-list中含有512條數(shù)據(jù),沒(méi)有超除配置文件中的限制
2、往test-list中再推入一條數(shù)據(jù)
此時(shí)test-list含有513條數(shù)據(jù),大于配置文件中限制的512條,索引將放棄ziplist存儲(chǔ)方式,采用其原來(lái)的linkedlist存儲(chǔ)方式
散列與有序集合同理。
2.2、intset整數(shù)集合(集合)
前提條件,集合中包含的所有member都可以被解析為十進(jìn)制整數(shù)。
以有序數(shù)組的方式存儲(chǔ)集合不僅可以降低內(nèi)存消耗,還可以提升集合操作的執(zhí)行速度。
配置:
set-max-intset-entries 512 #限制集合中member個(gè)數(shù),超出則不采取intset存儲(chǔ)
測(cè)試:
建立test.php文件
#test.php <?php $redis=new Redis(); $redis->connect('192.168.95.11','6379'); for ($i=0; $i<512 ; $i++) { $redis->sadd('test-set',$i); #給集合test-set插入512個(gè)member } ?>
2.3、性能問(wèn)題