Redis 內(nèi)存分析方法
線(xiàn)上經(jīng)常遇到用戶(hù)想知道自己 Redis 實(shí)例中數(shù)據(jù)的內(nèi)存分布情況。為了不影響線(xiàn)上實(shí)例的使用百揭,我們一般會(huì)采用 bgsave 生成 dump.rdb 文件母截,再結(jié)合 redis-rdb-tools 和 sqlite 來(lái)進(jìn)行靜態(tài)分析吧享》侠耄總的來(lái)說(shuō)撇寞,整個(gè)分析的過(guò)程簡(jiǎn)單而實(shí)用,是每一個(gè) Redis 的用戶(hù)都非常值得掌握的一個(gè)方法眨八。
自建 Redis 可在客戶(hù)端執(zhí)行?bgsave?生成 rdb 文件腺兴。云數(shù)據(jù)庫(kù) Redis 版可以在控制臺(tái)上可以進(jìn)行數(shù)據(jù)備份和下載的操作,下載后的數(shù)據(jù)為 rdb 格式文件廉侧。步驟詳見(jiàn)下圖:
下載阿里云? .rdb 文件
redis-rdb-tools 是一個(gè) python 的解析 rdb 文件的工具页响,在分析內(nèi)存的時(shí)候,我們主要用它生成內(nèi)存快照段誊。主要有以下三個(gè)功能:
生成內(nèi)存快照
轉(zhuǎn)儲(chǔ)成 json 格式
使用標(biāo)準(zhǔn)的 diff 工具比較兩個(gè) dump 文件
redis-rdb-tools 有兩種安裝方式闰蚕,任選其一即可。
使用 PYPI 安裝
pip install rdbtools
從源碼安裝
git clone https://github.com/sripathikrishnan/redis-rdb-tools
cd redis-rdb-tools
sudo python setup.py install
使用 redis-rdb-tools 生成內(nèi)存快照
生成內(nèi)存快照的命令為:
rdb -c memory dump.rdb > memory.csv
生成 CSV 格式的內(nèi)存報(bào)告连舍。包含的列有:數(shù)據(jù)庫(kù) ID没陡,數(shù)據(jù)類(lèi)型,key索赏,內(nèi)存使用量(byte)盼玄,編碼。內(nèi)存使用量包含 key潜腻、value 和其他值埃儿。
注意:內(nèi)存使用量是理論上的近似值,在一般情況下融涣,略低于實(shí)際值童番。memory.csv 例子:
$head memory.csv
database,type,key,size_in_bytes,encoding,num_elements,len_largest_element
0,string,"orderAt:377671748",96,string,8,8
0,string,"orderAt:413052773",96,string,8,8
0,sortedset,"Artical:Comments:7386",81740,skiplist,479,41
0,sortedset,"pay:id:18029",2443,ziplist,84,16
0,string,"orderAt:452389458",96,string,8,8
SQLite 是一款輕型的數(shù)據(jù)庫(kù)。我們可以將前面生成的 csv 導(dǎo)入到數(shù)據(jù)庫(kù)中之后威鹿,就可以利用 sql 語(yǔ)句很方便的對(duì) Redis 的內(nèi)存數(shù)據(jù)進(jìn)行各種分析了剃斧。
注意:SQLite版本必須是3.16.0以上。
導(dǎo)入方法
sqlite3 memory.db
sqlite>.help (查看幫助)
sqlite> create table memory(database int,type varchar(128),key varchar(128),size_in_bytes int,encoding varchar(128),num_elements int,len_largest_element varchar(128));
sqlite>.mode csv memory
sqlite>.import memory.csv memory
數(shù)據(jù)導(dǎo)入以后忽你,接下來(lái)想怎么分析就怎么分析了悯衬,舉幾個(gè)簡(jiǎn)單的例子:
查詢(xún)key個(gè)數(shù)
sqlite>select count(*) from memory;
查詢(xún)總的內(nèi)存占用
sqlite>select sum(size_in_bytes) from memory;
查詢(xún)內(nèi)存占用最高的10個(gè) key
sqlite>select * from memory order by size_in_bytes desc limit 10;
查詢(xún)成員個(gè)數(shù)1000個(gè)以上的 list
sqlite>select * from memory where type='list' and num_elements > 1000 ;
通過(guò)使用 redis-rdb-tools + sqlite 的方式,可以方便的對(duì) redis 實(shí)例的內(nèi)存情況進(jìn)行靜態(tài)的分析檀夹。整個(gè)過(guò)程也比較簡(jiǎn)單,獲取到 rdb 之后即可策橘。
rdb -c memory dump.rdb > memory.csv;
sqlite3 memory.db
sqlite> create table memory(database int,type varchar(128),key varchar(128),size_in_bytes int,encoding varchar(128),num_elements int,len_largest_element varchar(128));
sqlite>.mode csv memory
sqlite>.import memory.csv memory
實(shí)際使用中炸渡,發(fā)現(xiàn)過(guò)一個(gè) List 積攢了10多 GB 的內(nèi)容,也發(fā)現(xiàn)過(guò)43 MB 以上的 string 類(lèi)型的 value丽已, 往往不僅能解答用戶(hù)的疑惑蚌堵,而且能夠幫助用戶(hù)排除業(yè)務(wù)中潛在的風(fēng)險(xiǎn)點(diǎn),找到業(yè)務(wù)性能瓶頸。