標籤:
原文:Redis學習筆記4--Redis資料存放區最佳化機制
1.zipmap最佳化hash:
前面談到將一個Object Storage Service在hash類型中會佔用更少的記憶體,並且可以更方便的存取整個對象。省記憶體的原因是建立一個hash對象時開始是用zipmap來儲存的。這個zipmap其實並不是hash table,但是zipmap相比正常的hash實現可以節省不少hash本身需要的一些中繼資料存放區開銷。儘管zipmap的添加,刪除,尋找都是O(n),但是由於一般對象的field數量都不太多。所以使用zipmap也是很快的,也就是說添加刪除平均還是O(1)。如果field或者value的大小超出一定限制後,redis會在內部自動將zipmap替換成正常的hash實現。這個限制可以在設定檔中指定(預設配置在redis根目錄下的redis.conf中):
hash-max-zipmap-entries 512 #配置欄位最多512個hash-max-zipmap-value 64 #配置value最大為64位元組
2.ziplist最佳化list:
如果redisObject的type成員值是REDIS_LIST類型的,則當該list的元素個數小於配置值list-max-ziplist-entries且元素值字串的長度小於配置值list-max-ziplist-value則可以編碼成 REDIS_ENCODING_ZIPLIST 類型儲存,否則採用 Dict 來儲存(Dict實際是Hash Table的一種實現),list採用ziplist資料結構儲存資料,這樣做一方面為了節省記憶體,另一方面這種結構式順序儲存的結構,能夠更好利用cpu local和預取策略。
配置如下所示:
list-max-ziplist-entries 512 #配置元素個數最多512個list-max-ziplist-value 64 #配置value最大為64位元組
3.intset最佳化set:
當set集合中的元素為整數且元素個數小於配置set-max-intset-entries值時,使用intset資料結構儲存,否則轉化為Dict結構,Dict實際是Hash Table的一種實現,key為元素值,value為NULL,這樣即可在O(1)時間內判斷集合中是否包含某個元素。
intset中有三種類型數組:int16_t類型、int32_t 類型、 int64_t 類型。至於怎麼選擇是那種類型的數組,是根據其儲存的值的取值範圍來決定的,初始化時是 int16_t,根據 set 中的最大值在[INT16_MIN, INT16_MAX] , [INT32_MIN, INT32_MAX], [INT64_MIN, INT64_MAX]的那個取值範圍來動態確定整個數組的類型。例如set一開始是 int16_t 類型,當一個取值範圍在 [INT32_MIN, INT32_MAX]的值加入到 set 時,則將儲存 set 的數組升級成 int32_t 的數組。
intset元素限制的配置如下所示:
set-max-intset-entries 512 #配置元素個數最多512個
4.ziplist最佳化sorted set:
根hash和list一樣sorted set也有節約記憶體的方式,當sorted set的元素個數及元素大小小於一定限制時,它是用ziplist來儲存。
這個限制的配置如下:
zset-max-ziplist-entries 128 #配置元素個數最多512個zset-max-ziplist-value 64 #配置value最大為64位元組
5.小結:
Redis提供了很多關於最佳化記憶體的方法,上面這些配置的值都是預設配置,實際要根據我們具體的需求情境來調節,並要做大量的測試,以達到最優的效果。同時必須對Redis這些資料結構有很好的理解。
Redis記憶體儲存結構分析:http://www.searchtb.com/2011/05/redis-storage.html
Redis資料存放區最佳化機制(轉)