Redis是当前高并发场景下首选的分布式缓存组件,但是Redis并不是银弹,不合理的使用也会降低它的健康度,使Redis瞬间瘫痪。例如在系统开发过程中的不规范,经常会造成出现Redis Bigkey的情况,同时由于Redis主线程为单线程模型,Bigkey就会带来一些潜在隐患,比如:
- 集群模式在slot分片均匀情况下,会出现数据和查询倾斜情况,部分有Bigkey的Redis节点占用内存多,QPS较高
- Bigkey相关的删除或者自动过期时,会出现QPS突降或者突升的情况,极端情况下,会造成主从复制异常,Redis服务阻塞无法响应请求
Bigkey的体积与删除耗时参考如下:
==========================================================
当前列举了如下两种常用的方法来发现这些Bigkey,可以根据实际的要求选择合适的方法。
1)redis-rdb-tools
redis实例上执行bgsave,然后对dump出来的rdb文件进行分析,找到其中的大KEY
输出的信息包括数据类型,key、内存大小、编码类型等。
优点:在于获取的key信息详细、可选参数多、支持定制化需求,结果信息可选择json或csv格式,后续处理方便
缺点:需要离线操作,获取结果时间较长。
2)redis-cli --Bigkeys命令
Redis-cli --Bigkeys是redis-cli自带的一个命令。它对整个redis进行扫描,寻找较大的key,并打印统计结果。
输出的信息分为两部分,扫描过程部分,只显示了扫描到当前阶段里最大的key,summary部分给出了每种数据结构中最大的Key以及统计信息。
优点:可以在线扫描,不阻塞服务;
缺点:信息较少,内容不够精确,扫描结果中只有string类型是以字节长度为衡量标准的,List、set、zset等都是以元素个数作为衡量标准,元素个数多不能说明占用内存就一定多。
==========================================================
当发现这些Bigkey后如何删除来避免Redis服务出现堵塞异常,下面我们列举了两种方式,但具体使用方式我们会在后续的文章中再进行详细说明。
1)Redis4.0版本前只能通过hscan、sscan、zscan方式渐进删除若干个元素;但面对过期删除键的场景,这种取巧的删除就无能为力。
2)Redis4.0版本后引入了memory usage命令和lazyfree机制,不管是对Bigkey的发现,还是解决大Bigkey删除或者过期造成的阻塞问题都有明显的提升。
==========================================================
总结:在某些业务场景下,Bigkey的问题是难以避免的,但是以上这些特性有助于我们在实际业务中更好的预防Bigkey的产生和解决Bigkey造成的阻塞。