redis bigkey 解决 删除大key
大Key会带来的问题
- 如果是集群模式下,无法做到负载均衡,导致请求倾斜到某个实例上,而这个实例的QPS会比较大,内存占用也较多;对于Redis单线程模型又容易出现CPU瓶颈,当内存出现瓶颈时,只能进行纵向库容,使用更牛逼的服务器。
- 涉及到大key的操作,尤其是使用hgetall、lrange 0 -1、get、hmget 等操作时,网卡可能会成为瓶颈,也会到导致堵塞其它操作,qps 就有可能出现突降或者突升的情况,趋势上看起来十分不平滑,严重时会导致应用程序连不上,实例或者集群在某些时间段内不可用的状态。
- 假如这个key需要进行删除操作,如果直接进行DEL 操作,被操作的实例会被Block住,导致无法响应应用的请求,而这个Block的时间会随着key的变大而变长。
排查大key方法
- 在redis实例上执行bgsave,然后我们对dump出来的rdb文件进行分析,找到其中的大KEY
- 有个不太推荐的命令,debug object xxx 可以看到这个key在内存中序列化后的大小,当然我们可以通过SCAN+debug object xxx 得到当前实例所有key的大小。
- redis-cli 原生自带 –bigkeys 功能,可以找到某个实例 5种数据类型(String、hash、list、set、zset)的最大key。
开源rdb方式
安装
git clone https://github.com/sripathikrishnan/redis-rdb-tools
cd redis-rdb-tools
sudo python setup.py install
使用范例
rdb -c memory dump-10030.rdb > memory1.csv
redis-cli 原生自带 –bigkeys 方式
$ redis-cli -p 10030 --bigkeys -i 0.1
# 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 hash found so far '"REDIS_VIRTUAL_STORE_ORDER_ID_INITIALIZER"' with 13 fields
[00.00%] Biggest hash found so far '"REDIS_COUPON_USED_INITIALIZER"' with 3480 fields
[00.00%] Biggest hash found so far '"REDIS_USER_TICKET_INITIALIZER"' with 68017 fields
[00.00%] Biggest string found so far 'THD_INVOKE_RESULT:":com.dianrong.mkts.service.thirdparty.service.CoreServiceRemote::getPlanInfoByPlanId:3513058"' with 5 bytes
[00.00%] Biggest list found so far '"QUEUE_AWARD_NUM_KEY"' with 7 items
-------- summary -------
Sampled 14 keys in the keyspace!
Total key length in bytes is 667 (avg len 47.64)
Biggest string found 'THD_INVOKE_RESULT:":com.dianrong.mkts.service.thirdparty.service.CoreServiceRemote::getPlanInfoByPlanId:3513058"' has 5 bytes
Biggest list found '"QUEUE_AWARD_NUM_KEY"' has 7 items
Biggest hash found '"REDIS_USER_TICKET_INITIALIZER"' has 68017 fields
2 strings with 10 bytes (14.29% of keys, avg size 5.00)
1 lists with 7 items (07.14% of keys, avg size 7.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
11 hashs with 196712 fields (78.57% of keys, avg size 17882.91)
0 zsets with 0 members (00.00% of keys, avg size 0.00)
可以发现 Biggest hash found so far '"REDIS_USER_TICKET_INITIALIZER"' with 68017 fields 异常的大
删除方法
注意删除超过 maxmemory redis进程挂掉,慎重删除!
127.0.0.1:10030> keys '*REDIS_USER_TICKET_INITIALIZER*'
127.0.0.1:10030> del "\"REDIS_USER_TICKET_INITIALIZER\""