Redis記憶體模型

2021-08-15 07:59:29 字數 2909 閱讀 2616

五:理解記憶體

1.記憶體消耗

1)物件記憶體

redis所有資料均採用keyvalue資料型別,每次建立鍵值對時,至少建立兩個型別物件:key物件和value物件,物件記憶體=sizeof(keys)+sizeof(values)

key物件均為字串,value物件包括:string、hash、list、set、zset。每種value物件型別根據使用規模不同,占用記憶體不同

2)緩衝記憶體

主要包括:客戶端緩衝、複製擠壓緩衝、aof緩衝

* 客戶端緩衝(所有接入到redis伺服器tcp連線的輸入輸出緩衝區。輸入緩衝無法控制,最大為1g,超過將斷開連線;輸出緩衝通過引數client-output-buffer-limit控制,具體值如下:)

3)記憶體碎片

redis預設的記憶體分配器是 jemalloc,可選的分配器還有:glibc、tcmalloc

記憶體分配器為了更好的管理和重複利用記憶體,分配記憶體策略一般採用固定範圍的記憶體塊進行分配。

jemalloc在64位作業系統中將記憶體空間劃分為:小、大、巨大三個範圍,每個範圍又劃分多個小的記憶體塊單位

* 小:[8byte][16byte][32byte]...

* 大:[4kb]

[8kb][12kb]...

* 巨:[4mb][8mb][12mb]...

例:當儲存5kb的物件時,會採用8kb的塊儲存,而剩下的3kb空間就成了空間碎片而不能再分配給其他物件

易出現碎片的場景:

* 大量過期鍵刪除 (鍵物件刪除後,釋放的空間無法得到充分利用)

碎片空間解決方案:

* 資料對齊 (資料計量採用數字型別或者固定長度字串)

* 安全重啟 (重啟節點可以將記憶體碎片重新整理)

4)子程序記憶體消耗

主要是指執行aof/rdb重寫時redis建立的子程序記憶體消耗。

redis執行fork操作產生的子程序記憶體佔用量對外表現為與父程序相同,理論上需要一倍的物理記憶體來完成重寫操作。但linux的寫時複製技術,父子程序會共享相同的物理記憶體頁

子程序記憶體消耗總結:

* redis產生的子程序並不需要消耗1倍的父程序記憶體,實際消耗根據期間寫入命令量來決定,但是依然需要預留出一些記憶體防止溢位

* 需要設定sysct1 vm.overcommit_memrory=1 允許核心可以分配所有的物理記憶體,防止redis執行fork時因系統剩餘記憶體不足而失敗

* 排查當前系統是否支援並開啟thp,如果開啟建議關閉            

2.記憶體管理

redis主要通過控制記憶體上線和**策略實現記憶體管理

1)設定記憶體上限

* 設定configure 設定redis.conf裡的maxmemory

* 動態設定 config set maxmemory xxgb

2)記憶體**策略

* 刪除過期key物件

* 記憶體溢位控制策略刪除key物件

記憶體溢位控制策略如下:

可以在redis.conf中設定,也可以使用 config set maxmemory-policy 來設定

3.記憶體優化

1)redisobject

redis儲存的所有值物件在內部定義為redisobject,該值物件具體屬性有:

降低redis記憶體最直接的方式就是:縮減key和value的長度

2)縮減鍵值物件

盡量去掉不必要的屬性字段

3)共享物件池

redis內部維護[0-9999]的整數物件池,當value屬於這個值範圍,可以使用使用物件池中的資料。

4)字串優化

* 字串結構:redis自實現了字串結構,包括三個屬性(int len:已用位元組長度 int free:未用位元組長度 char buf:位元組陣列)

* 特點:o(1)時間複雜度;可用於儲存位元組陣列,支援安全的二進位制資料儲存;內部實現空間預分配機制,降低記憶體再分配次數;惰性刪除,字串縮減後的空間不釋放,作為預分配空間保留

* 預分配機制:由於存在預分配,資料大量追加後會造成記憶體碎片率上公升

* 字串重構:json這樣的資料可以考慮使用hash來儲存

5)編碼優化

控制編碼型別,多用具有壓縮功能的編碼型別

6)控制鍵的數量

不要把redis當做單純的key-value來使用,適當的可以考慮使用其他型別來儲存,控制鍵的數量,降低記憶體使用

Redis記憶體模型

3.4.1 refcount與共享物件 緩衝區溢位 使用c字串的api時,如果字串長度增加 如strcat操作 而忘記重新分配記憶體,很容易造成緩衝區的溢位 而sds由於記錄了長度,相應的api在可能造成緩衝區溢位時會自動重新分配記憶體,杜絕了緩衝區溢位。修改字串時記憶體的重分配 對於c字串,如果要...

redis記憶體模型

檢視記憶體info memory redis分配器分配的記憶體總量 位元組 used memory 24989816 redis分配器分配的記憶體總量 used memory human 23.83m redis程序佔據作業系統的記憶體 位元組 used memory rss 36409344 us...

Redis記憶體模型 2 儲存細節

先看一下執行set hellow world時,所涉及的資料模型 1 dictentry redis是key value資料庫,因此對每個鍵值對都會有乙個dictentry,裡面儲存了指向key和value的指標 next指向下乙個dictentry,與本key value無關。2 key 圖中右上...