Redis數(shù)據(jù)存儲(chǔ)優(yōu)化機(jī)制詳解
zipmap優(yōu)化hash
將一個(gè)對(duì)象存儲(chǔ)在hash類型中會(huì)占用更少的內(nèi)存,并且可以更方便的存取整個(gè)對(duì)象。省內(nèi)存的原因是新建一個(gè)hash對(duì)象時(shí)開始是用zipmap來存儲(chǔ)的。這個(gè)zipmap其實(shí)并不是hash table,但是zipmap相比正常的hash實(shí)現(xiàn)可以節(jié)省不少hash本身需要的一些元數(shù)據(jù)存儲(chǔ)開銷。盡管zipmap的添加,刪除,查找都是O(n),但是由于一般對(duì)象的field數(shù)量都不太多。所以使用zipmap也是很快的,也就是說添加刪除平均還是O(1)。
如果field或者value的大小超出一定限制后,redis會(huì)在內(nèi)部自動(dòng)將zipmap替換成正常的hash實(shí)現(xiàn)。這個(gè)限制可以在配置文件中指定(默認(rèn)配置在redis根目錄下的redis.conf中):
- hash-max-zipmap-entries 512 #配置字段最多512個(gè)
- hash-max-zipmap-value 64 #配置value***為64字節(jié)
ziplist優(yōu)化list
如果redisObject的type成員值是REDIS_LIST類型的,則當(dāng)該list的元素個(gè)數(shù)小于配置值list-max-ziplist-entries,且元素值字符串的長(zhǎng)度小于配置值list-max-ziplist-value,
則可以編碼成 REDIS_ENCODING_ZIPLIST 類型存儲(chǔ),否則采用 Dict 來存儲(chǔ)(Dict實(shí)際是Hash Table的一種實(shí)現(xiàn)),list采用ziplist數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)數(shù)據(jù),這樣做一方面為了節(jié)省內(nèi)存,另一方面這種結(jié)構(gòu)式順序存儲(chǔ)的結(jié)構(gòu),能夠更好利用cpu local和預(yù)取策略。
配置如下所示:
- list-max-ziplist-entries 512 #配置元素個(gè)數(shù)最多512個(gè)
- list-max-ziplist-value 64 #配置value***為64字節(jié)
intset優(yōu)化set
當(dāng)set集合中的元素為整數(shù)且元素個(gè)數(shù)小于配置set-max-intset-entries值時(shí),使用intset數(shù)據(jù)結(jié)構(gòu)存儲(chǔ),否則轉(zhuǎn)化為Dict結(jié)構(gòu),Dict實(shí)際是Hash Table的一種實(shí)現(xiàn),key為元素值,value為NULL,這樣即可在O(1)時(shí)間內(nèi)判斷集合中是否包含某個(gè)元素。
intset中有三種類型數(shù)組:int16_t類型、int32_t 類型、 int64_t 類型。至于怎么選擇是那種類型的數(shù)組,是根據(jù)其保存的值的取值范圍來決定的,初始化時(shí)是 int16_t,根據(jù) set 中的***值在[INT16_MIN, INT16_MAX] , [INT32_MIN, INT32_MAX], [INT64_MIN, INT64_MAX]的那個(gè)取值范圍來動(dòng)態(tài)確定整個(gè)數(shù)組的類型。例如set一開始是 int16_t 類型,當(dāng)一個(gè)取值范圍在 [INT32_MIN, INT32_MAX]的值加入到 set 時(shí),則將保存 set 的數(shù)組升級(jí)成 int32_t 的數(shù)組。
intset元素限制的配置如下所示:
- set-max-intset-entries 512 #配置元素個(gè)數(shù)最多512個(gè)
ziplist優(yōu)化sorted set
根hash和list一樣sorted set也有節(jié)約內(nèi)存的方式,當(dāng)sorted set的元素個(gè)數(shù)及元素大小小于一定限制時(shí),它是用ziplist來存儲(chǔ)。
這個(gè)限制的配置如下:
- zset-max-ziplist-entries 128 #配置元素個(gè)數(shù)最多512個(gè)
- zset-max-ziplist-value 64 #配置value***為64字節(jié)
小結(jié)
Redis提供了很多關(guān)于優(yōu)化內(nèi)存的方法,上面這些配置的值都是默認(rèn)配置,實(shí)際要根據(jù)我們具體的需求場(chǎng)景來調(diào)節(jié),并要做大量的測(cè)試,以達(dá)到***的效果。同時(shí)必須對(duì)Redis這些數(shù)據(jù)結(jié)構(gòu)有很好的理解。