Redis 中 String 型別的記憶體開銷比較大

2022-09-23 15:39:09 字數 2644 閱讀 4676

如果我們有大量的資料需要來儲存,在選型資料型別我們就需要知道 string 的記憶體開銷是很大的

這裡我們來分析下使用乙個 string 型別需要用到的記憶體

redis 中的 string,使用的是簡單動態字串(****** dynamic strings,sds)。

來看下資料結構

struct sdshdr ;
如果,使用 sds 儲存了乙個字串 hello,對應的 len 就是5,同時也申請了5個為未使用的空間,所以 free 就是5。對於 buf 來說,len 和 free 的記憶體占用都是額外開銷。

因為 redis 中有很多資料型別,對於這些不同的資料結構,redis 為了能夠統一處理,所以引入了 redisobject。

typedef struct redisobject  robj;
乙個 redisobject 包含了8位元組的元資料和乙個8位元組指標,指標指向實際的資料記憶體位址。

不過需要注意的是這裡 redis 做了優化

1、當儲存的資料是 long 型別整數時,redisobjec t中的指標就直接賦值為整數資料了,就不用使用額外的指標了。

2、如果儲存的是字串資料,並且字串大小小於等於44位元組時,redisobject中的元資料、指標和sds是一塊連續的記憶體區域,這樣就可以避免記憶體碎片。這種布局方式也被稱為 embstr 編碼方式。

3、如果儲存的是字串資料,並且字串大小大於44位元組時,redis 就不再把 sds 和 redisobject 布局在一起了,而是會給 sds 分配獨立的空間,並用指標指向 sds 結構。這種布局方式被稱為 raw 編碼模式。

這個引用一張redis核心技術與實戰中的

redis 中會有乙個全域性的雜湊表來儲存所有的鍵值對,雜湊表中每一項儲存的是 dictentry 結構體

typedef struct dictentry  v;

struct dictentry *next;

} dictentry;

dictentry 結構體中有三個指標,在64位機器下佔24個位元組,jemalloc 會為它分配32位元組大小的記憶體單元。

jemalloc 作為 redis 的預設記憶體分配器,在減小記憶體碎片方面做的相對比較好。jemalloc 在64位系統中,將記憶體空間劃分為小、大、巨大三個範圍;每個範圍內又劃分了許多小的記憶體塊單位;當 redis 儲存資料時,會選擇大小最合適的記憶體塊進行儲存。

所以選用 string 型別來儲存字串,上面的 redisobject 結構、sds 結構、dictentry 結構的都會存在一定的記憶體開銷

redis 中的底層資料結構,提供了壓縮列表,這種是很節省記憶體空間的。

我們可以使用 hash 這種資料結構,因為在一定情況下這種結構底層的用的是壓縮列表,這是一種很節省記憶體的資料結構。

關於壓縮列表的細節可參見redis中的壓縮列表

這些entry會挨個兒放置在記憶體中,不需要再用額外的指標進行連線,這樣就可以節省指標所占用的空間。

redis基於壓縮列表實現了 hash 這樣的集合型別,因為乙個集合可以儲存多個鍵值對,使用乙個鍵值對就能對應到這個集合中了。使用 string 型別時,乙個鍵值對就對應乙個 dictentry,這點對於使用集合型別來講也是節省記憶體的乙個點。

使用集合我們還需要注意一下幾點:

1、我們要去保證存放到集合中的元素不要太多,使用 ziplist 作為內部資料結構的限制元素數預設不超過 512 個。可以通過修改配置來調整zset_max_ziplist_entries閥值的大小。如果超過了限制就不使用 ziplist 而是使用 hash 型別來實現這個對映關係了。

2、同時元素也不能太少,如果乙個 hash 集合中只存入了一對filed/value,就相當於每個鍵值對也使用了乙個全域性的雜湊表的 dictentry。

3、同時鍵值對的 value 也不要太長,超過了hash-max-ziplist-value的限制也是會使用 hash 型別而不是 ziplist。

原來使用 string 型別儲存,是乙個k/v結構,使用 hash 型別,就需要兩個 key 了,可以將原來的k/v中的 k 進行拆分,分成兩部分即可。

127.0.0.1:6379> set 202220222111 xiaoming

ok127.0.0.1:6379> hset 20222 0222111 xiaoming

(integer) 1

string 型別的元資料是會占用一部分的記憶體空間,如果我們的資料,單個資料不大,但是數量很多,選用 string 這種型別的時候,需要考慮一下記憶體的占用。

【redis核心技術與實戰】

【redis設計與實現】

【redis 一組kv實際記憶體占用計算】

【redis學習筆記】

【redis 中 string 型別的記憶體開銷比較大】中的string型別記憶體開銷比較大/

redis中string型別及其操作

新增乙個name guo的鍵值對 set name guo get name guo setnx name guo new integer 0 get name guo 原來的name有乙個對應的值,所以本次的修改不生效,返回0 設定key對應的value並且指定此鍵值的有效期 setex colo...

redis語法 String型別

127.0.0.1 6379 set k1 v1 ok127.0.0.1 6379 get k1 v1 127.0.0.1 6379 del k1 integer 1 127.0.0.1 6379 get k1 nil 127.0.0.1 6379 set k2 v2 ok integer 9 12...

redis的資料型別 string

1.string型別 2.方法 1.set 設定key對應的值為string 型別的 value。例 set name cl 設定name 的值為cl 成功返回 ok 多次設定 值會覆蓋 2.setns 設定key對應的值為string 型別的 value,如果值已經存在,返回0 設定失敗。使用這個...