内存分析能提取业务特点,了解业务瓶颈,发现业务Bug。比如一些用户说他们的Key并不多,但是内存却已满,分析后才发现,一个List有16G,相当于把售卖的数据都放到了同一个Key里面。业务量不多的时候没问题,业务量增加的时候,Key就已经很大了,说明当前的代码已经远远跟不上业务的发展。
内存分析方法有两种,一种在线,一种离线。一般采用离线方法,离线内存分析是把Redis的数据存下来,放到本地,不会有风险,数据可以任意操作,主要分为3步:一是生成rdb文件(bgsave),二是生成内存快照,三是分析内存快照。每一步都很简单,生成内存快照会用到一个开源的工具,Redis-rdb-tools,用来做rdb文件的分析。命令为db -c memory dump.rdb > memory.csv。生成的内存快照为csv格式,包含:
Database:数据库ID
Type:数据类型
Key:
size_in_bytes:理论内存值(比实际略低)
Encoding:编码方式
num_elements:成员个数
len_largest_element:最大成员长度
其中每一个Key都有六列数据,表明属于第几号数据库,这里要注意理论内存值,会比实际略低。程序员可以将生成后的快照导入到数据库,可以用sqlite,然后进行数据分析,这里简单列举几条。
查询Key个数:sqlite> select count(*) from memory;
查询总的内存占用:sqlite> select sum(size_in_bytes) from memory;
查询内存占用最高的10个Key:sqlite> select * from memory order by size_in_bytes desc limit 10;
查询成员个数1000个以上的list:sqlite> select * from memory where type='list' and num_elements > 1000 ;
接下来是在线内存分析,这里以简单的Redis-cli为例,有一个-bigKeys的选项,可以把每种类型Key的最大Key找出来。
在这里再分享两个其他的内存分析问题。有时候Redis产品可能并没有多少东西,内存却满了,从而排查出来是其他方面的内存占用。一个可能是client占用内存的关系,因为用rdb分析的时候没有client,线上的很多连接都会带着一个很长的命令,Redis里面就会有缓存,dict rehash也会占用一些内存。内存分析时发现有一些哈希表的内存占据特别大,因为有些Key很少被访问,导致rehash被很少触发,中间缓存的表会一直删不掉。这里可以用一个脚本访问触发rehash,看内存是否变化,把表删掉即可。
原地址:https://mp.weixin.qq.com/s/n4HXKXPKf87qgZ_e6s4gPg