工作中,经常有些Redis实例使用不恰当,或者对业务预估不准确,或者key没有及时进行处理等等原因,导致某些KEY相当大。
那么大Key会带来哪些问题呢?
- 如果是集群模式下,无法做到负载均衡,导致请求倾斜到某个实例上,而这个实例的QPS会比较大,内存占用也较多;对于Redis单线程模型又容易出现CPU瓶颈,当内存出现瓶颈时,只能进行纵向库容,使用更牛逼的服务器。
- 涉及到大key的操作,尤其是使用hgetall、lrange 0 -1、get、hmget 等操作时,网卡可能会成为瓶颈,也会到导致堵塞其它操作,qps 就有可能出现突降或者突升的情况,趋势上看起来十分不平滑,严重时会导致应用程序连不上,实例或者集群在某些时间段内不可用的状态。
- 假如这个key需要进行删除操作,如果直接进行DEL 操作,被操作的实例会被Block住,导致无法响应应用的请求,而这个Block的时间会随着key的变大而变长。
有以下几种办法可以知道某个Redis实例是否存在大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。
通过Redis-cli –bigkeys 我们可以很方便的找到某个实例最大的几个KEY,但是只能得到某种类型的最大的一个key,于是思考改改redis-cli findBigKeys 功能,增加查找多个key的代码,用户可以指定大key的数量。
修改后功能预览如下:
VITOXIE-MB1:src xiean$ ./redis-cli-new -p 2837 --bigkeys --bigkey-numb 3
Biggest string Key Top 1 found 'xxxG_NEWMATCH_VOD_DATA_7f7a2a2fb5f780a13fecd9f1e51bdf8a' has 53170 bytes
Biggest string Key Top 2 found 'xxxG_NEWMATCH_VOD_DATA_a9758560d1874493c637dec0753909da' has 53159 bytes
Biggest string Key Top 3 found 'xxxG_NEWMATCH_VOD_DATA_d0971977b0ce028141e53b020b93d822' has 53156 bytes
Biggest list Key Top 1 found 'UserPostInfo122_632789064' has 11028 items
Biggest list Key Top 2 found 'xxxG_FriendCallBack_PushList_23' has 1973 items
Biggest list Key Top 3 found 'xxxG_FriendCallBack_PushList_20' has 1824 items
ps,修改的源码放在GitHub上,这里还部分dba日常实用工具:https://github.com/xiepaup/OPS-Tools ,欢迎探讨。