一、特殊編碼:
自從Redis 2.2之後,許多資料型別都可以透過特殊編碼的方式來進行儲存空間的最佳化。其中,Hash、List和由Integer組成的Sets都可以透過此方式來最佳化儲存結構,以便佔用較少的空間,在有些情況下,可以省去9/10的空間。 (建議:redis影片教學)
這些特殊編碼對於Redis的使用而言是完全透明的,事實上,它只是CPU和記憶體之間的交易而言。如果記憶體使用率方面高一些,那麼在操作資料時消耗的CPU自然要多一些,反之亦然。在Redis中提供了一組配置參數用於設定與特殊編碼相關的各種閾值,如:
#如果Hash中字段的数量小于参数值,Redis将对该Key的Hash Value采用特殊编码。 hash-max-zipmap-entries 64 #如果Hash中各个字段的最大长度不超过512字节,Redis也将对该Key的Hash Value采用特殊编码方式。 hash-max-zipmap-value 512 #下面两个参数的含义基本等同于上面两个和Hash相关的参数,只是作用的对象类型为List。 list-max-ziplist-entries 512 list-max-ziplist-value 64 #如果set中整型元素的数量不超过512时,Redis将会采用该特殊编码。 set-max-intset-entries 512
倘若某個已經被編碼的值再經過修改之後超過了配置資訊中的最大限制,那麼Redis會自動將其轉換為正常編碼格式,這一操作是非常快速的,但是如果反過來操作,將一個正常編碼的較大值轉換為特殊編碼,Redis的建議是,在正式做之前最好先簡單測試一下轉換效率,因為這樣的轉換往往是非常低效的。
二、BIT和Byte層級的操作:
##從Redis 2.2開始,Redis提供了GETRANGE/SETRANGE/GETBIT/SETBIT四個用於字串類型Key /Value的命令。透過這些指令,我們便可以像運算元一樣來存取String類型的值資料了。 例如唯一標識使用者身分的ID,可能只是String值的其中一段子字串。這樣就可以透過GETRANGE/SETRANGE指令來方便的提取。 再有就是可以使用BITMAP來表示使用者的性別訊息,如1表示male,0表示female。用這種方式來表示100,000,000個使用者的性別資訊時,也僅僅佔用12MB的儲存空間,同時,在透過SETBIT/GETBIT指令進行資料遍歷也是非常有效率的。三、盡可能使用Hash:
由於小的Hash類型資料佔用的空間相對較少,因此我們在實際應用時應該盡可能的考慮使用Hash類型,例如用戶的註冊訊息,其中包括姓名、性別、email、年齡和口令等欄位。 我們當然可以將這些資訊以Key的形式進行存儲,而用戶填寫的資訊則以String Value的形式儲存。然而Redis則更為建議以Hash的形式存儲,以上資訊則以Field/Value的形式表示。 現在我們就透過學習Redis的儲存機制來進一步證明這個說法。在該篇部落格的開始處已經提到了特殊編碼機制,其中有兩個和Hash類型相關的配置參數:hash-max-zipmap-entries和hash-max-zipmap-value。 至於它們的作用範圍前面已經給出,這裡就不再過多的贅述了。現在我們先假設儲存在Hash Value中的欄位數量小於hash-max-zipmap-entries,而每個元素的長度同時又小於hash-max-zipmap-value。這樣每當有新的Hash類型的Key/Value儲存時,Redis都會為Hash Value建立定長的空間,最大可預先分配的位元組數為:total_bytes = hash-max-zipmap-entries * hash-max-zipmap-value這樣一來,Hash中所有欄位的位置已經預留,可以像存取陣列那樣隨機的存取Field/Value,他們之間的步長間隔為hash-max-zipmap-value。 只有當Hash Value中的字段數量或某一新元素的長度分別超過以上兩個參數值時,Redis才會考慮將他們以Hash Table的方式進行重新存儲,否則將始終保持這種高效率的儲存和存取方式。 不僅如此,由於每個Key都要儲存一些關聯的系統信息,如過期時間、LRU等,因此和String類型的Key/Value相比,Hash類型極大的減少了Key的數量(大部分的Key都以Hash字段的形式表示並儲存了),從而進一步優化了儲存空間的使用效率。 更多redis知識請關注
redis資料庫教學欄位。
以上是redis記憶體優化方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!