Redis大key優化方案

前言

因爲redis是單線程運行的,若是一次操做的value很大會對整個redis的響應時間形成負面影響,因此業務上一般會以如下方式進行分拆。redis

分拆

單個key存儲大value

每次都是整存整取api

這種操做通常都是每次整存整取,這種狀況能夠嘗試將對象拆分紅多個key-value,使用multiGet獲取值,這樣分拆意義在於分拆操做的壓力,將操做壓力平攤到多個redis實例,下降對於單個redis的io壓力。線程

每次只存取部分數據指針

一樣能夠拆成幾個key-value,也能夠將這些存儲在一個hash中,每一個field表明具體屬性,使用hget,hmget來獲取部分value,使用hset,hmset來更新部分屬性。對象

hash,set,zset,list中存儲過多數據

一樣能夠將這部分元素拆分,以hash爲例,正常的流程是:hget(hashKey, field);hset(hashKey, field, value)。 如今能夠固定一個桶數量,好比1w,每次存取的時候,先在本地計算field的hash值,對1w取模,肯定field落在哪一個key上。內存

newHashKey = hashKey + ( hash(field) % 10000); hset (newHashKey, field, value) ; hget(newHashKey, field)路由

set,zset,list作法相似。get

一個集羣存儲了上億的key

若是key個數過多會帶來更多的內存佔用空間:hash

  1. key自己佔用。
  2. 集羣中,服務端會創建slot2key的映射關係,這種指針佔用在key多的狀況下存在巨大的空間浪費,在key上億時,內存消耗十分明顯。

減小key個數能夠減小對內存的消耗,能夠參考hash結構存儲,將多個key存儲在一個hash結構中。it

組合那些key自己強相關性的,好比key表明一個對象,m每一個key是對象的一個屬性,按照這種方式設置一個新的key-hash的結構,原先的key做爲這個新hash field。

好比:

將user.zhangsan.id= 123,user.zhangsan.age = 18,user.zhangsan.country = china 改爲 key = user.zhangsan field:id = 123 field:age = 18 field:country = china

若是key自己沒有相關性,能夠預估總量,對一些場景預分固定的桶數量。

好比有2億key,按照一個hash存儲100個field來算,須要200w個桶,這樣能夠按照200w個固定桶數量作取模,hash(123456) % 200w,好比算出3個key的桶分別是1,2,3。調用存儲api hset(key, field, value),讀取時用hget(key,field)。 建議分桶數量100合適。

Bitmap和Bloom拆分

使用Bloom的場景每每是數據量極大的狀況,這種狀況下,bitmap和bloom使用空間比較大。

若是bitmap比較大,能夠拆分紅多個小的bitmap,能夠經過結合hash方式,將key路由到hash上對應的bitmap上,將不一樣的key分配給不一樣的bitmap,而不是全部小的bitmap看成一個總體,這樣每次請求都只要取redis中的一個key便可。

相關文章
相關標籤/搜索