步骤一:快速找出大Key和热Key
阿里云控制台工具
Tair和Redis在控制台提供了Top Key统计和离线全量Key分析功能帮助您快速找出大Key与热Key。
方法 | 使用限制 | 说明 | 操作步骤 |
Top Key统计(推荐) | 仅Redis开源版5.0及以上版本和Tair(企业版)内存型、持久内存型支持该功能。 | | 访问实例列表,在上方选择地域,然后单击目标实例ID。 在左侧导航栏,单击或离线全量Key分析。
|
离线全量Key分析 | 单副本实例或磁盘型实例不支持该功能。 | |
如果您的实例不能使用上述功能,请参考以下方法。
其他方法找出大Key和热Key
方法 | 优缺点 | 说明 |
通过redis-cli的bigkeys、memkeys和hotkeys参数 | | redis-cli的bigkeys、memkeys与hotkeys参数能获取Key的整体统计信息与每个数据类型中Top1的大Key或热Key。 区别如下: 支持的数据类型:STRING、LIST、HASH、SET、ZSET、STREAM。 以bigkeys为例,命令示例为redis-cli -h r-***************.redis.rds.aliyuncs.com -a <password> --bigkeys 。 |
通过内置命令对目标Key进行分析 | | 对不同数据类型的目标Key,分别通过如下风险较低的命令进行分析,来判断目标Key是否符合大Key判定标准。 STRING类型:STRLEN命令,返回对应Key的value的字节数。 LIST类型:LLEN命令,返回对应Key的列表长度。 HASH类型:HLEN命令,返回对应Key的成员数量。 SET类型:SCARD命令,返回对应Key的成员数量。 ZSET类型:ZCARD命令,返回对应Key的成员数量。 STREAM类型:XLEN命令,返回对应Key的成员数量。
说明 DEBUG OBJECT与MEMORY USAGE命令在执行时需占用较多资源,且时间复杂度为O(N),有阻塞实例的风险,不建议使用。 |
通过业务层定位热Key | | 通过在业务层增加相应的代码对实例的访问进行记录并异步汇总分析。 |
通过redis-rdb-tools工具以定制化方式找出大Key | 优点:支持定制化分析,对线上服务无影响。 缺点:时效性差,RDB文件较大时耗时较长。
| Redis-rdb-tools是通过Python编写的开源工具,支持定制化分析RDB快照文件。下载RDB文件后,您可以根据业务需求分析实例中所有Key的内存占用情况,并支持灵活地查询。 |
通过MONITOR命令找出热Key | | MONITOR命令能够忠实地打印实例中的所有请求,包括时间信息、Client信息、命令以及Key信息。 在发生紧急情况时,可以通过短暂执行MONITOR命令并将返回信息输入至文件,在关闭MONITOR命令后,对文件中请求进行归类分析,找出这段时间中的热Key。 说明 由于MONITOR命令对实例性能消耗较大,非特殊情况不推荐使用MONITOR命令。 |
步骤二:优化大Key与热Key
大Key
方案 | 适用场景 | 操作建议 |
清理过期数据 | 大量过期数据堆积,如HASH中未清理的增量数据。 | 通过HSCAN命令配合HDEL命令对失效数据进行清理,避免清理大量数据造成实例阻塞。 |
压缩大Key | JSON、XML文本数据等可压缩数据,如日志、配置。 | 说明 压缩和解压缩操作需要消耗额外的CPU资源,可能影响处理性能。 |
拆分大Key | 高频访问的HASH、ZSET等,如排行榜。 | 拆分大Key能有效避免数据倾斜。 |
转存大Key | String类型大文件或BLOB。 | 将不适用数据存至其它存储(如OSS),并在实例中删除此类数据。 |
热Key
方案 | 适用场景 | 操作建议 |
在集群架构中对热Key进行复制 | 热Key作为整体存储在单一分片,无法通过迁移部分数据分散请求。 | 将热Key复制并迁移至其他数据分片,例如将热Key foo复制出3个内容完全一样的Key并命名为foo2、foo3、foo4,将这三个Key迁移到其他数据分片来解决单个数据分片的热Key压力。 说明 该方案的缺点是需修改代码维护多个副本,且多副本间的数据一致性难以保障(例如更新操作需同步所有副本)。建议将该方案作为临时解决方案,用于缓解紧急问题。 |
开启读写分离功能 | 读多写少 | 如果开启后读请求负载依旧很高,可通过增加只读节点数量进一步缓解读请求负载。 说明 在请求量极大的场景下,主从同步会产生不可避免的延迟,此时会出现读取到脏数据的问题。因此,在读、写压力都较大且对数据一致性要求很高的场景下,不推荐开启读写分离。 |
开启QueryCache功能 | 重复命令查询相同Key | 开启该功能后,Tair和Redis会根据算法识别出热Key(通常热Key的QPS大于5,000),代理节点Proxy会缓存热Key的请求和查询结果(仅缓存热Key的查询结果,无需缓存整个Key)。在缓存有效时间内收到相同的请求时,Proxy会直接返回结果至客户端,无需和后端的数据分片执行交互。 |
步骤三:预防大Key和热Key影响业务
大Key和热Key产生的原因
Tair和Redis的最小数据分布粒度为Key。单个Key将存储在特定的数据分片中,且不会被拆分。业务规划不足、无效数据的堆积以及访问量的突增等因素,均会使实例产生大Key与热Key,如:
类别 | 原因 |
大Key | 在不适用的场景下使用Tair和Redis,易造成Key的value过大,如使用String类型的Key存放大体积二进制文件型数据; 业务上线前规划设计不足,没有对Key中的成员进行合理的拆分,造成个别Key中的成员数量过多; 未定期清理无效数据,造成如HASH类型Key中的成员持续不断地增加; 使用LIST类型Key的业务消费侧发生代码故障,造成对应Key的成员只增不减。
|
热Key | |
大Key和热Key带来的影响
类别 | 影响 |
大Key | 客户端执行命令的时长变慢。 实例内存达到maxmemory上限时,可能导致操作阻塞、重要Key被逐出,甚至内存溢出(OOM)。 集群架构下,某个数据分片的内存使用率远超其他数据分片,无法使数据分片的内存资源达到均衡。 对大Key执行读请求,会使实例的带宽使用率被占满,导致自身服务变慢,同时易波及相关的服务。 对大Key执行删除操作,易造成主库较长时间的阻塞,进而可能引发同步中断或主从切换。
|
热Key | 占用大量的CPU资源,同时可能增加网络带宽的使用,进而影响其他请求并导致整体性能降低。 集群架构下,产生访问倾斜,即某个数据分片被大量访问,而其他数据分片处于空闲状态,可能引起该数据分片的连接数被耗尽,新的连接建立请求被拒绝等问题。 在抢购或秒杀场景下,可能因商品对应库存Key的请求量过大,超出实例处理能力造成超卖。 热Key的请求压力数量超出实例的承受能力,容易造成缓存击穿,即大量请求将被直接指向后端的存储层,导致存储访问量激增甚至宕机,从而影响其他业务。
|
预防策略
策略 | 说明 |
监控报警设置 | 设置合理的CPU、内存、连接数使用率等报警阈值进行报警,例如内存使用率超过70%、内存在1小时内增长率超过20%等。出现报警时,按照本文步骤一和步骤二的指引定位并优化大Key和热Key,在其发展到影响业务之前解决。 |
使用Tair(企业版)避开失效数据的清理工作 | 针对hash类型的大key场景,Tair(企业版)提供了增强型数据结构 TairHash。它支持为每个 field 设置过期时间和版本。通过合理使用 TairHash,可以显著减少运维负担、简化业务代码复杂度,并有效应对大 Key 和热 Key 带来的问题。 |