redis value最大值 redis記憶體優化

2021-10-14 00:26:17 字數 3046 閱讀 8503

小的聚合型別資料的特殊編碼處理

redis2.2版本及以後,儲存集合資料的時候會採用記憶體壓縮技術,以使用更少的記憶體儲存更多的資料。如hashes,lists,sets和sorted sets,當這些集合中的所有數都小於乙個給定的元素,並且集合中元素數量小於某個值時,儲存的資料會被以一種非常節省記憶體的方式進行編碼,使用這種編碼理論上至少會節省10倍以上記憶體(平均節省5倍以上記憶體)。並且這種編碼技術對使用者和redis api透明。因為使用這種編碼是用cpu換記憶體,所以我們提供了更改閾值的方法,只需在redis.conf裡面進行修改即可.

hash-max-zipmap-entries 64 (2.6以上使用hash-max-ziplist-entries)hash-max-zipmap-value 512 (2.6以上使用hash-max-ziplist-value)list-max-ziplist-entries 512list-max-ziplist-value 64zset-max-ziplist-entries 128zset-max-ziplist-value 64set-max-intset-entries 512
(集合中)如果某個值超過了配置檔案中設定的最大值,redis將自動把把它(集合)轉換為正常的雜湊表。這種操作對於比較小的數值是非常快的,但是,如果你為了使用這種編碼技術而把配置進行了更改,你最好做一下基準測試(和正常的不採用編碼做一下對比).

使用32位的redis

使用32位的redis,對於每乙個key,將使用更少的記憶體,因為32位程式,指標占用的位元組數更少。但是32的redis整個例項使用的記憶體將被限制在4g以下。使用make 32bit命令編譯生成32位的redis。rdb和aof檔案是不區分32位和64位的(包括位元組順序),所以你可以使用64位的reidis恢復32位的rdb備份檔案,相反亦然.

位級別和字級別的操作

redis 2.2引入了位級別和字級別的操作: getrange, setrange, getbit 和 setbit.使用這些命令,你可以把redis的字串當做乙個隨機讀取的(位元組)陣列。例如你有乙個應用,用來標誌使用者的id是連續的整數,你可以使用乙個位圖標記使用者的性別,使用1表示男性,0表示女性,或者其他的方式。這樣的話,1億個使用者將僅使用12 m的記憶體。你可以使用同樣的方法,使用 getrange 和 setrange 命令為每個使用者儲存乙個位元組的資訊。這僅是乙個例子,實際上你可以使用這些原始資料型別解決更多問題。

盡可能使用雜湊表(hashes)

小雜湊表(是說雜湊表裡面儲存的數少)使用的記憶體非常小,所以你應該盡可能的將你的資料模型抽象到乙個雜湊表裡面。比如你的web系統中有乙個使用者物件,不要為這個使用者的名稱,姓氏,郵箱,密碼設定單獨的key,而是應該把這個使用者的所有資訊儲存到一張雜湊表裡面.

使用雜湊結構高效儲存抽象的鍵值對

我知道這部分的標題很嚇人,但是我將詳細解釋這部分內容.

一般而言,把乙個模型(model)表示為key-value的形式儲存在redis中非常容易,當然value必須為字串,這樣儲存不僅比一般的key value儲存高效,並且比memcached儲存還高效.

讓我們做個對比:一些key儲存了乙個物件的多個欄位要比乙個雜湊表儲存物件的多個字段占用更多的記憶體。這怎麼可能?從原理上講,為了保證查詢乙個資料總是在乙個常量時間內(o(1)),需要乙個常量時間複雜度的資料結構,比如說雜湊表.

但是,通常情況下,雜湊表只包括極少的幾個字段。當雜湊表非常小的時候,我們採用將資料encode為乙個o(n)的資料結構,你可以認為這是乙個帶有長度屬性的線性陣列。只有當n是比較小的時候,才會採用這種encode,這樣使用hget和hset命令的複雜度仍然是o(1):當雜湊表包含的元素增長太多的時候,雜湊表將被轉換為正常的雜湊表(極限值可以在redis.conf進行配置).

無論是從時間複雜度還是從常量時間的角度來看,採用這種encode理論上都不會有多大效能提公升,但是,乙個線性陣列通常會被cpu的快取更好的命中(線性陣列有更好的區域性性),從而提公升了訪問的速度.

既然雜湊表的字段及其對應的值並不是用redis objects表示,所以雜湊表的字段不能像普通的key一樣設定過期時間。但是這毫不影響對雜湊表的使用,因為雜湊表本來就是這樣設計的(我們相信簡潔比多功能更重要,所以嵌入物件是不允許的,雜湊表字段設定單獨的過期時間是不允許的).

所以雜湊錶能高效利用記憶體。這非常有用,當你使用乙個雜湊表儲存乙個物件或者抽象其他一類相關的字段為乙個模型時。但是,如果我們有乙個普通的key value業務需求怎麼辦?

假如我們想使用redis儲存許多小物件,這些物件可以使用json字串表示,也可能是html片段和簡單的key->boolean鍵值對。概況的說,一切皆字串,都可以使用string:string的形式表示.

我們假設要快取的物件使用數字字尾進行編碼,如:

我們可以這樣做。每次set的時候,把key分為兩部分,第一部分當做乙個key,第二部當做雜湊表字段。比如「object:1234」,分成兩部分:

我們使用除最後2個數字的部分作為key,最後2個數字做為雜湊表的字段。使用命令:

hset object:12 34 somevalue
如你所見,每個雜湊表將(理論上)包含100個字段,這是cpu資源和記憶體資源之間的乙個折中.

另乙個需要你關注的是在這種模式下,無論快取多少物件,每個雜湊表都會分配100個字段。因為我們的物件總是以數字結尾,而不是乙個隨機的字串。從某些方面來說,這是一種隱性的預分片。

對於小數字怎麼處理?比如object:2,我們採用object:作為key,所有剩下的數字作為乙個字段。所以object:2和object:10都會被儲存到key為object:的雜湊表中,但是乙個使用2作為字段,乙個使用10作為字段。

這種方式將節省多少記憶體?

我使用了下面的ruby程式進行了測試:

require 'rubygems'require 'redis'useoptimization = truedef hash_get_key_field(key) s = key.split(":") if s[1].length > 2  else {:key => s[0]+":

redis value最大值 Redis 原理篇

位圖 用redis點陣圖節約儲存空間 set s h 整存 setbit s 1 1 設定第一位為1 get s 整取 getbit s 12 獲取第12位 bitfield w get u3 2 從第3位開始取 取3位作為無符號數 bitfield w set u8 8 97 從第9位開始 接下來...

int 最大值 239 滑動視窗最大值

給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗內的 k 個數字。滑動視窗每次只向右移動一位。返回滑動視窗中的最大值。示例 輸入 nums 1,3,1,3,5,3,6,7 和 k 3 輸出 3,3,5,5,6,7 解釋 滑動視窗的位置 最大...

算式最大值

演算法給定 1 n個正整數a1,a2,an 2 p個加號 和q個減號 p q n 1 3 k對括號 請你使用全部整數 加減號和括號,組成乙個合法的算式 a1 an在算式中的順序隨意 使得算式的結果最大。注意加減號只能作為二元運算子出現在算式中,不能作為正負號。括號可以出現在算式最左和最右,例如 1 ...