五:理解記憶體
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 圖中右上...