今天解決一個(gè)redis內(nèi)存使用量大的問題。和大家分享一下。
有一個(gè)歷史遺留系統(tǒng)A,因?yàn)橐恍I(yè)務(wù)原因,申請了很大的redis內(nèi)存。從40G一路加到了80G。但是仍然經(jīng)常告警,達(dá)到了max_memory。
聯(lián)系系統(tǒng)用戶,刪除了大量數(shù)據(jù)。查看內(nèi)存,仍然處于緊張狀態(tài)。
查了一些資料。
redis的內(nèi)存使用構(gòu)成
我們查詢r(jià)edis的內(nèi)存使用:
info memory
used_memory Redis:分配器分配的內(nèi)存量,也就是實(shí)際存儲(chǔ)數(shù)據(jù)的內(nèi)存總量
used_memory_human:以可讀格式返回 Redis 使用的內(nèi)存總量
used_memory_rss:從操作系統(tǒng)的角度,Redis進(jìn)程占用的總物理內(nèi)存
used_memory_peak:內(nèi)存分配器分配的最大內(nèi)存,代表used_memory的歷史峰值
used_memory_peak_human: 以可讀的格式顯示內(nèi)存消耗峰值
used_memory_lua:Lua引擎所消耗的內(nèi)存
mem_fragmentation_ratio:used_memory_rss /used_memory比值,表示內(nèi)存碎片率
mem_allocator:Redis 所使用的內(nèi)存分配器。默認(rèn): jemalloc
計(jì)算公式如下:
used_memory = 自身內(nèi)存+對象內(nèi)存+緩沖內(nèi)存+lua內(nèi)存
used_rss = used_memory + 內(nèi)存碎片
如下圖所示:
3.1.2 內(nèi)存分析
- 1) 自身內(nèi)存:一個(gè)空的Redis占用很小,可以忽略不計(jì)
- 2) kv內(nèi)存:key對象 + value對象
- 3) 緩沖區(qū):客戶端緩沖區(qū)(普通 + slave偽裝 + pubsub)以及aof緩沖區(qū)(比較固定,一般沒問題)
- 4) Lua:Lua引擎所消耗的內(nèi)存
內(nèi)存突增常見問題
- 1) kv內(nèi)存:bigkey、大量寫入
- 2) 客戶端緩沖區(qū):一般常見的有普通客戶端緩沖區(qū)(例如monitor命令)或者pubsub客戶端緩沖區(qū)
可能出現(xiàn)的問題排查
- 1) bigkey?
redis --bigkeys:可以對redis整個(gè) keyspace 進(jìn)行統(tǒng)計(jì)(數(shù)據(jù)量大時(shí)采樣,調(diào)用 scan 命令),尋找每種數(shù)據(jù)類型較大的 keys,給出數(shù)據(jù)統(tǒng)計(jì) redis-cli --bigkeys -i 0.1 -h 127.0.0.1
- 2) 鍵值個(gè)數(shù)增加?
- 3) 客戶端緩沖區(qū)
如果是因?yàn)榫彌_區(qū)問題,會(huì)從info clients找到明顯問題。重點(diǎn)觀察是否明顯的omem大于0的情況。
- 4) Redis的kv哈希表做了 rehash
問題解決
本次遇到的問題是客戶端緩沖區(qū)問題,使用如下命令
redis-cli -c -h x.x.x.x -p 6398 -a xxxx client list | grep -v 'omem=0'
查詢緩沖器非0的客戶端
發(fā)現(xiàn)有一個(gè)客戶端持有了大量內(nèi)存緩沖。將對應(yīng)的應(yīng)用重啟后。內(nèi)存使用量一下子降下來了。






