Write by lyc at 2019-1-6
分析redis key大小的几种方法

分析Redis key大小的三种方式

  1. --bigKeys redis-cli 自带的一个参数,缺点是只能对 string类型的key获取bytes数,其他类型的只能获取到元素len()个数/长度
  2. debug object key 登录redis下的某个db,获取key的信息。缺点是结果中的serializedlength是key的序列化长度,并不是key的实际bytes大小,不准确。
  3. rdbtools 工具,生成内存报告。精确的获取redis实例下的所有key的内存报告,通过shell或excel排序。(推荐使用)

方法1:bigKeys 查看string类型key大小

redis-cli 命令自带的一个参数,对整个redis实例进行扫描,寻找较大的key

该命令使用scan方式对key进行统计,所以使用时无需担心对redis造成阻塞。

输出大概分为两部分,summary之上的部分,只是显示了扫描的过程。summary部分给出了每种数据结构中最大的Key。

统计出的最大key只有string类型是以字节长度为衡量标准的。list,set,zset等都是以元素个数作为衡量标准,不能说明其占的内存就一定多。所以,如果你的Key主要以string类型存在,这种方法就比较适合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ /usr/local/redis/bin/redis-cli  -h 127.0.0.1 -p 6379 --bigkeys

# Scanning the entire keyspace to find biggest keys as well as
# average sizes per key type. You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).

[00.00%] Biggest string found so far '742ee4d2e271468e93262057a155813a.jpg' with 102 bytes
[00.02%] Biggest string found so far 'fe0fc54786bd4a95a353a05789968878.jpg' with 103 bytes
[11.03%] Biggest string found so far 'fcc12d11e322443b9c15bf06e1a9cf79.jpg' with 104 bytes

-------- summary -------

Sampled 87531 keys in the keyspace!
Total key length in bytes is 3151192 (avg len 36.00)

Biggest string found 'fcc12d11e322443b9c15bf06e1a9cf79.jpg' has 104 bytes

87531 strings with 8889404 bytes (100.00% of keys, avg size 101.56)
0 lists with 0 items (00.00% of keys, avg size 0.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 hashs with 0 fields (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
0 streams with 0 entries (00.00% of keys, avg size 0.00)

方法2:debug object key

redis的命令,可以查看某个key序列化后的长度,使用前先登录redis

1
2
3
127.0.0.1:6379[16]> select 16
127.0.0.1:6379[16]> debug object "Astor:Virgo"
Value at:0x7fcdfd63afc0 refcount:1 encoding:raw serializedlength:4837 lru:1218639 lru_seconds_idle:1115

输出结果说明:

  • Value at key的内存地址
  • refcount 引用次数
  • encoding 编码类型
  • serializedlength 序列化长度,key的大小参考这个值
  • lru_seconds_idle 空闲时间

serializedlength 说明

  • serializedlength 是key序列化后的长度(redis在将key保存为rdb文件时使用了该算法),并不是key在内存中的真正长度。这就像一个数组在json_encode后的长度与其在内存中的真正长度并不相同。不过,它侧面反应了一个key的长度,==可以用于比较两个key的大小。==
  • serializedlength 会对字串做一些可能的压缩。如果有些字串的压缩比特别高,那么在比较时会出现问题。
  • 需要准确获取keys的占用空间大小,不推荐用这种方式。

方法3:rdbtools 工具生成内存报告(推荐使用)

在线字节转换工具

rdbtools 工具安装

1
$ pip3 install rdbtools

首次执行分析会提示加载慢,需要另外安装 python-lzf

1
2
3
4
$ rdb -c memory dump-6379.rdb > /data/6379keys.log
WARNING: python-lzf package NOT detected. Parsing dump file will be very slow unless you install it. To install, run the following command:

$ pip install python-lzf

使用 rdbtools 生成Redis内存报告

  • 首先我们需要有一份rdb文件,如果你在配置中开启了rdb,那么redis会自动生成rdb文件。
  • 如果没有,可以手动执行 bgsave。如果是线上机器,执行时要考虑机器负载等问题。
  • 拿到rdb文件后,我们就可以生成内存报告了。命令如下:
1
$ rdb -c memory dump-6379.rdb

查看所有key的内存报告

  • 输出了db,数据类型,key, 大小, 编码等多列信息。
  • 至于分析数据,你可以用shell,也可以保存成csv用excel排序,或者干脆存到db里,想怎么排怎么排。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ rdb -c memory dump-6379.rdb > /data/6379keys.log
database,type,key,size_in_bytes,encoding,num_elements,len_largest_element,expiry
1,string,link_user_to_gtpost_tb:EnqueueList:F7AE047B9E37BE70B0462B024E66B9B0:Count,152,string,8,8,2020-01-06T06:18:37.923000
1,list,link_user_to_gtpost_tb:EnqueueList:D9359DA60026D86F1FE72E327F024386,651,quicklist,2,202,2020-01-05T07:03:56.976000
1,string,WoChao_Post_5414_Praises_Count,72,string,8,8,
1,sortedset,75199AF3779E7461DE81F6AF4B115DE0,437,ziplist,43,8,
1,list,link_user_to_gtpost_tb:EnqueueList:177B94BB063EAD8CB40F25597B88D267,1653,quicklist,7,200,2020-01-05T04:47:10.561000
1,string,WoChao_Post_216451_Praises_Count,80,string,8,8,
1,sortedset,BD6E0BD01DCDDCAF52161C74359ABBEA,123,ziplist,4,8,
1,string,WoChao_Post_169130_Praises_Count,80,string,8,8,
1,string,WoChao_Post_18054_Praises_Count,80,string,8,8,
1,sortedset,5173C37A89A34B41DE1D022CEE43C27C,691,ziplist,75,8,
1,string,WoChao_Post_118897_Praises_Count,80,string,8,8,
1,string,WoChao_Post_277261_Praises_Count,80,string,8,8,
.....

只查看最大n个key

1
$ rdb -c memory -l 100 dump-6379.rdb > /data/keyszie_top100.log

查看单个key

如果我们只需要查询单个key所使用的内存可以不必依赖rdb file, 使用 redis-memory-for-key 命令即可。

1
2
3
4
$ redis-memory-for-key -s 127.0.0.7 -p 6379 -d 16 "Astor:Virgo"
Key Astor:Virgo
Bytes 8248
Type string