说明
若您只需要分析STRING类型的大key或是找出成员数量超过10个的HASH Key,则
bigkeys
参数无法直接实现该类需求。
同时,自Redis 4.0版本起提供了
hotkeys
参数,可以快速帮您找出业务中的热Key,具体操作,请参见
通过redis-cli的hotkeys参数查找热Key
。
对不同数据类型的目标Key,分别通过如下风险较低的命令进行分析,来判断目标Key是否符合大Key判定标准。
STRING类型:执行
STRLEN
命令,返回对应Key的value的字节数。
LIST类型:执行
LLEN
命令,返回对应Key的列表长度。
HASH类型:执行
HLEN
命令,返回对应Key的成员数量。
SET类型:执行
SCARD
命令,返回对应Key的成员数量。
ZSET类型:执行
ZCARD
命令,返回对应Key的成员数量。
STREAM类型:执行
XLEN
命令,返回对应Key的成员数量。
对大Key进行拆分
例如将含有数万成员的一个HASH Key拆分为多个HASH Key,并确保每个Key的成员数量在合理范围。在Redis集群架构中,拆分大Key能对数据分片间的内存平衡起到显著作用。
对大Key进行清理
将不适用Redis能力的数据存至其它存储,并在Redis中删除此类数据。
Redis 4.0及之后版本:您可以通过
UNLINK
命令安全地删除大Key甚至特大Key,该命令能够以非阻塞的方式,逐步地清理传入的Key。
Redis 4.0之前的版本:建议先通过
SCAN
命令读取部分数据,然后进行删除,避免一次性删除大量key导致Redis阻塞。
监控Redis的内存水位
您可以通过监控系统设置合理的Redis内存报警阈值进行提醒,例如Redis内存使用率超过70%、Redis的内存在1小时内增长率超过20%等。通过此类监控手段,可以提前规避许多问题,例如LIST数据类型的消费程序故障造成对应Key的列表数量持续增长,将告警转变为预警从而避免故障的发生,更多信息,请参见
报警设置
。
对过期数据进行定期清理
堆积大量过期数据会造成大Key的产生,例如在HASH数据类型中以增量的形式不断写入大量数据而忽略了数据的时效性。可以通过定时任务的方式对失效数据进行清理。
说明
在清理HASH数据时,建议通过
HSCAN
命令配合
HDEL
命令对失效数据进行清理,避免清理大量数据造成Redis阻塞。
使用阿里云的Tair服务(Redis企业版)避开失效数据的清理工作
若HASH Key过多,存在大量的成员失效需要被清理的问题,又由于大量Key与大量失效数据叠加,无法通过定时任务对无效数据进行及时地清理,您可以通过阿里云Tair服务高效地解决此类问题。
Tair是云数据库Redis的企业版,它具备Redis所有特性(包括Redis的高性能特点),同时提供了大量额外的高级功能。
TairHash是一种可为field设置过期时间和版本的HASH数据类型,它不但和Redis Hash一样支持丰富的数据接口和高处理性能,还改变了Hash只能为Key设置过期时间的限制,可以为field设置过期时间和版本。这极大地提高了HASH数据类型的灵活性,简化了很多场景下的业务开发工作。同时,TairHash使用高效的Active
Expire算法,实现了在对响应时间几乎无影响的前提下,高效完成对field过期判断和删除的功能。
此类高级功能的合理使用能够解放大量Redis的运维、故障处理工作并降低业务的代码复杂度,更多信息,请参见
TairHash命令
。
在Redis集群架构中对热Key进行复制
在Redis集群架构中,由于热Key的迁移粒度问题,无法将请求分散至其他数据分片,导致单个数据分片的压力无法下降。此时,可以将对应热Key进行复制并迁移至其他数据分片,例如将热Key
foo复制出3个内容完全一样的Key并名为foo2、foo3、foo4,将这三个Key迁移到其他数据分片来解决单个数据分片的热Key压力。
说明
该方案的缺点在于需要联动修改代码,同时带来了数据一致性的挑战(由原来更新一个Key演变为需要更新多个Key),仅建议该方案用来解决临时棘手的问题。
使用读写分离架构
如果热Key的产生来自于读请求,您可以将实例改造成读写分离架构来降低每个数据分片的读请求压力,甚至可以不断地增加从节点。但是读写分离架构在增加业务代码复杂度的同时,也会增加Redis集群架构复杂度。不仅要为多个从节点提供转发层(如Proxy,LVS等)来实现负载均衡,还要考虑从节点数量显著增加后带来故障率增加的问题。Redis集群架构变更会为监控、运维、故障处理带来了更大的挑战。
然而,阿里云Redis服务以开箱即用的方式提供服务。在业务发生变化时,您仅需通过变配的方式调整实例架构来轻松应对,例如将主从架构转变为读写分离架构、将读写分构架构转变为集群架构,以及将社区版转变为支持大量高级特性的Tair版(Redis企业版)等,更多信息,请参见
变更实例配置
。
说明
读写分离架构同样存在缺点,在请求量极大的场景下,读写分离架构会产生不可避免的延迟,此时会有读取到脏数据的问题。因此,在读、写压力都较大且对数据一致性要求很高的场景下,读写分离架构并不是最优方案。
使用阿里云Tair的QueryCache特性
云数据库Redis会根据高效的排序和统计算法识别出实例中存在的热点Key(通常热点Key的QPS大于3,000),开启该功能后,代理节点Proxy会根据设定的规则缓存热点Key的请求和查询结果(仅缓存热点Key的查询结果,无需缓存整个Key)。当在缓存有效时间内收到相同的请求时,Proxy会直接返回结果至客户端,无需和后端的数据分片执行交互。在提升读取速度的同时,降低了热点Key对数据分片的性能影响,避免访问倾斜。
开通该功能后,来自客户端的同样请求无需再与Proxy后端的Redis进行交互而是由Proxy直接返回数据,指向热Key的请求由一个Redis节点承担转为多个Proxy共同承担,能够大幅度降低Redis节点的热Key压力。同时Tair的QueryCache功能还提供了大量的命令来方便您查看、管理代理查询缓存的情况,例如通过
querycache keys
命令查看所有被缓存热Key,通过
querycache listall
命令获取所有已缓存的所有命令等。更多信息,请参见
通过Proxy Query Cache优化热点Key问题
。