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