作者:个推数据库工程师 嘉木
个推作为国内第三方推送市场的早期进入者,专注于为开发者提供高效稳定的推送服务,经过9年的积累和发展,服务了包括新浪、滴滴在内的数十万APP。由于我们推送业务对并发量、速度要求很高,为此,我们选择了高性能的内存数据库Redis。然而,在实际业务场景中我们也遇到了一些Redis大key造成的服务阻塞问题,因此积累了一些应对经验。本文将对大key的发现、解决大key删除造成的阻塞做相应的介绍。
Redis大key的一些场景及问题
大key场景
Redis使用者应该都遇到过大key相关的场景,比如:
1、热门话题下评论、答案排序场景。
2、大V的粉丝列表。
3、使用不恰当,或者对业务预估不准确、不及时进行处理垃圾数据等。
大key问题
由于Redis主线程为单线程模型,大key也会带来一些问题,如:
1、集群模式在slot分片均匀情况下,会出现数据和查询倾斜情况,部分有大key的Redis节点占用内存多,QPS高。
2、大key相关的删除或者自动过期时,会出现qps突降或者突升的情况,极端情况下,会造成主从复制异常,Redis服务阻塞无法响应请求。大key的体积与删除耗时可参考下表:
key类型 field数量耗时
Hash~100万~1000ms
List~100万~1000ms
Set~100万~1000ms
Sorted Set~100万~1000ms
Redis 4.0之前的大key的发现与删除方法
1、redis-rdb-tools工具。redis实例上执行bgsave,然后对dump出来的rdb文件进行分析,找到其中的大KEY。
2、redis-cli --bigkeys命令。可以找到某个实例5种数据类型(String、hash、list、set、zset)的最大key。
3、自定义的扫描脚本,以Python脚本居多,方法与redis-cli --bigkeys类似。
4、debug object key命令。可以查看某个key序列化后的长度,每次只能查找单个key的信息。官方不推荐。
redis-rdb-tools工具
关于rdb工具的详细介绍请查看链接https://github.com/sripathikrishnan/redis-rdb-tools,在此只介绍内存相关的使用方法。基本的命令为 rdb -c memory dump.rdb (其中dump.rdb为Redis实例的rdb文件,可通过bgsave生成)。
输出结果如下:
database,type,key,size_in_bytes,encoding,num_elements,len_largest_element
0,hash,hello1,1050,ziplist,86,22,
0,hash,hello2,2517,ziplist,222,8,
0,hash,hello3,2523,ziplist,156,12,
0,hash,hello4,62020,hashtable,776,32,
0,hash,hello5,71420,hashtable,1168,12,
可以看到输出的信息包括数据类型,key、内存大小、编码类型等。Rdb工具优点在于获取的key信息详细、可选参数多、支持定制化需求,结果信息可选择json或