redis記憶體引數

2021-07-25 11:28:47 字數 2978 閱讀 2499

下面這些redis記憶體方面的問題是在工作中發現的。可以作為乙個工作中的參考

一、redis資料型別的特殊編碼形式

在redis2.2以後許多資料型別為了節約記憶體使用大小,都開啟了乙個壓縮的演算法,當資料庫中的

元素個數少於配置檔案中設定的檔案個數時,這些元素最理想的情況下會被壓縮到10分之一的大小進行儲存,

(一般情況下可以壓縮到5分之一),從而節約記憶體占用。

這些配置對於使用的人來說非常清晰,這些配置其實也是記憶體 和cpu之間的乙個權衡,壓縮會占用cpu,不壓縮記憶體使用

就較高。在不同的機器或者應用場景下,開發人員應該進行乙個抉擇,以下是一些基本的預設配置項:

hash-max-zipmap-entries 512 (hash-max-ziplist-entries for redis >= 2.6)

hash-max-zipmap-value 64  (hash-max-ziplist-value for redis >= 2.6)

list-max-ziplist-entries 512

list-max-ziplist-value 64

zset-max-ziplist-entries 128

zset-max-ziplist-value 64

set-max-intset-entries 512

上面的第乙個配置和第二個配置的意思,就是說 hashmap 已經壓縮的實體數量在少於512個,並且元素的大小低於64的時候就會自動被壓縮記憶體。

注意事項:

1、如果乙個經過壓縮的元素大於設定的最大元素大小,redis會取消壓縮,當儲存的資料不是特別大的時候,壓縮操作還是比較快的。

2、但是如果你改變了預設的配置,去壓縮一下比較大的元素資料,還是非常建議你做一下壓力測試,並且檢查一下壓縮所占用的時間和cpu.

二、32位的作業系統

1、redis在32的機器的上因為指標變數只有四個位元組,因此占用的記憶體相對會更小,但是由於32位的作業系統其最大記憶體只能支援到4g。

2、rdb和aof不管是在32位和64位的機器上(包括大端和小端),都是相容的。

三、bit和byte 不同儲存級別操作

redis2.2以後提供了四個命令,

getrange

, setrange

, getbit

and 

setbit

.用來擷取指定長度的字串,舉個例子,

如果你要儲存id從 1-1億  個使用者的性別,你可以使用二進位制的0和1來表示性別,這樣你大概只需要使用12m的記憶體就可以

儲存1個億的使用者的性別資料,而在查詢或者設定資料的時候你可以使用getbit和setbit命令。當然你也可以使用getrange和setrange在byte層面來做乙個優化。

四、使用hashmap代替多個key

舉個例子,比如在web應用中你有乙個user物件包含了

name, surname, email, password等屬性

,這個時候你最好使用hashmap,

五、關於hashmap

如果你使用的是string型別,那麼它的訪問效率是高於memcache的,但是它會比memcache更消耗記憶體。

乙個hasmap儲存乙個物件,比單個儲存物件的屬性要更加節約記憶體,比如

你有乙個user物件包含了

name, surname, email, password。當我們使用hashmap的使用,當hashmap中的鍵值對較少的時候redis會以陣列的形式來進行儲存,當hashmap中的鍵值對過多的時候redis才會把它變成真正的hash。

從時間複雜度來說這並不是很好,但是從恆定時間的觀點上來看,key- value對的線性陣列很好地利用了cpu 的快取(

它的快取位置比hash好)。

在hashmap中不能使用expire了,當然多維的也是不允許的,這是redis的設計原則。

hash包含100個字段在cpu和記憶體之間儲存是最理想的。

另外如果你能夠使用乙個盡量小的數字來作為key或者value,也會非常節約記憶體。比如乙個hashtable,

users > array ('userid:1'=>'json','userid:2'=>'json'),其實你可以直接簡化filed為 1,2這種型別

六、redis中的記憶體分配

1、 redis在啟動時會分配使用者在配置檔案中指定的

maxmemory記憶體(可能會有額外的消耗)。

2、當redis在刪除乙個鍵的時候,redis不會立即釋放記憶體,熟悉malloc的應該知道分配運算不太容易能釋放記憶體,

通常乙個記憶體頁上有的鍵還存在,有的鍵則已經刪除,那這個頁面該如何釋放呢。

比如,你的redis有5g的資料,即使你刪除了2g的資料,常駐記憶體的大小(

也被稱為rss,它是記憶體頁的數量消耗

)也仍然接近5g,儘管redis可能顯示的記憶體使用是3g左右。 3、

4、然而分配運算子malloc會很聰明地區重新使用空閒的記憶體塊,因此你的5g  的資料釋放2g之後,當你重新新增更多的key時,即使你增加的key資料達到2g,你將看見rss(常駐記憶體大小)保持穩定沒有增長。分配符主要是去嘗試使用之前釋放的記憶體(邏輯上釋放的記憶體)。

5、redis在記憶體碎片上的整理做得還不夠出色,詳細可見jmalloc的實現原理,

所以,當你發現你的記憶體使用比平常大了許多的時候,你就應該注意了

。碎片率的計算是目前使用的記憶體(redis執行分配的記憶體)除以實際分配的物理記憶體(rss的值)。由於rss是最大記憶體,當很多key/value被釋放,就會導致記憶體的使用率非常低,但是rss很高,

因此mem_used / rss就非常高. 6、

如果沒有設定maxmemoryredis就會一直分配能找到的記憶體並且逐步地吃光所有的空閒記憶體。因此一般都要明確地配置限制。你也可以設定maxmemory-policy為noeviction(在redis以前的一些版本不是預設值).

這可以使當redis的記憶體使用達到限制值時,返回記憶體溢位錯誤。

redis常用記憶體優化手段與引數

通過上面的實現上的分析,可以看出redis的記憶體管理成本比較高,即占用了過多的記憶體,redis的作者對這點也很清楚,所以提供了一系列的引數和手段來控制和節省記憶體 首先最重要的一點是不要開啟redis的vm選項,即虛擬記憶體功能。這個本來是作為redis儲存超出物理記憶體資料的一種資料在記憶體與...

redis引數優化

redis記憶體管理方式,支援tcmalloc,jemalloc,malloc三種記憶體分配,memcache使用slabs,malloc等記憶體分配方式。簡單點,就是redis,是邊用邊申請,使用現場申請記憶體的方式來儲存資料,並且很少使用free list等方式來優化記憶體分配 memcache...

Redis 記憶體優化

非常感謝 redis內部有很多的資料型別,這些在官方文件上都可以看到,下面是其內部優化的一些細節點 1.string 和 數字,在redis中如果儲存的是 123 redis是能夠識別出來這是乙個數字並且按照數字來儲存,節省儲存空間,當然除了這個優化之外,redis內部會構建乙個數字池,預設是100...