Redis 大key和热key问题及处理

一、说说什么是Redis、及特点?

Redis是一个基于内存存储数据运行并支持持久化、使用key/value形式存储的高性能的nosql数据库,适合用于存储频繁访问,数据量较小的场景下。

特点:

  1. 支持数据持久化:可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
  2. 支持多种数据结构:不仅支持简单的key-value类型数据,同时还提供string、list、set、zset、hash等数据结构的存储
  3. 支持数据备份:master-salve模式的数据备份

二、什么是大key

通常我们会将含有较大数据或含有大量成员、列表数的Key称之为大Key,下面我们将用几个实际的例子对大Key的特征进行(量化)描述:

  1. 一个STRING类型的Key,它的值为5MB(数据过大)
  2. 一个LIST类型的Key,它的列表数量为20000个(列表数量过多)
  3. 一个ZSET类型的Key,它的成员数量为10000个(成员数量过多)
  4. 一个HASH格式的Key,它的成员数量虽然只有1000个但这些成员的value总大小为100MB(成员体积过大)

三、什么是热Key

在某个Key接收到的访问次数、显著高于其它Key时,我们可以将其称之为热Key,常见的热Key如:

  1. 某Redis实例的每秒总访问量为10000,而其中一个Key的每秒访问量达到了7000(访问次数显著高于其它Key)
  2. 对一个拥有上千个成员且总大小为1MB的HASH Key每秒发送大量的HGETALL(带宽占用显著高于其它Key)
  3. 对一个拥有数万个成员的ZSET Key每秒发送大量的ZRANGE(CPU时间占用显著高于其它Key)

四、大Key与热Key带来的问题

在Redis的使用中,大Key及热Key会给Redis带来各种各样的问题,而最常见的问题为性能下降、访问超时、数据不均衡等。

4.1 大Key带来的常见问题

  1. Client发现Redis变慢;
  2. Redis内存不断变大引发OOM,或达到maxmemory设置值引发写阻塞或重要Key被逐出;
  3. Redis Cluster中的某个node内存远超其余node,但因Redis Cluster的数据迁移最小粒度为Key而无法将node上的内存均衡化;
  4. 大Key上的读请求使Redis占用服务器全部带宽,自身变慢的同时影响到该服务器上的其它服务;
  5. 删除一个大Key造成主库较长时间的阻塞并引发同步中断或主从切换;

4.2 热Key带来的常见问题

  1. 热Key占用大量的Redis CPU时间使其性能变差并影响其它请求;
  2. Redis Cluster中各node流量不均衡造成Redis Cluster的分布式优势无法被Client利用,一个分片负载很高而其它分片十分空闲从而产生读/写热点问题;
  3. 在抢购、秒杀活动中,由于商品对应库存Key的请求量过大超出Redis处理能力造成超卖;
  4. 热Key的请求压力数量超出Redis的承受能力造成缓存击穿,此时大量强求将直接指向后端存储将其打挂并影响到其它业务;

五、大Key与热Key的常见产生原因

业务规划不足、Redis不正确的使用、无效数据的堆积、访问突增等都会产生大Key与热Key,如:

  1. 将Redis用在并不适合其能力的场景,造成Key的value过大,如使用String类型的Key存放大体积二进制文件型数据(大Key);
  2. 业务上线前规划设计考虑不足没有对Key中的成员进行合理的拆分,造成个别Key中的成员数量过多(大Key);
  3. 没有对无效数据进行定期清理,造成如HASH类型Key中的成员持续不断的增加(大Key);
  4. 预期外的访问量陡增,如突然出现的爆款商品、访问量暴涨的热点新闻、直播间某大主播搞活动带来的大量刷屏点赞、游戏中某区域发生多个工会间的战斗涉及大量玩家等(热Key);
  5. 使用LIST类型Key的业务消费侧代码故障,造成对应Key的成员只增不减(大Key);

六、找出Redis中的大Key与热Key

大Key与热Key的分析并不困难,我们有多种途径和手段来对Redis中的Key进行分析并找出其中的"问题"Key,如Redis的内置功能、开源工具、阿里云Redis控制台中的Key分析功能等。

七、大key的处理方法

大key的处理方法有两种:

  1. 拆分
  2. 删除
拆分:

如将一个成员很多的hash拆分为多个hash。

删除:

将不适合Redis能力的数据存放至其它存储,并在Redis中删除此类数据。需要注意的是,删除大key可能很耗时,redis又是单线程执行的,很可能造成阻塞,Redis自4.0起提供了UNLINK命令,该命令能够异步的方式安全的删除大Key。

八、热key的处理方法

热key的处理方法有两种:

  1. 复制
  2. 读写分离
  3. 多级缓存
    复制:

在使用redis集群时,可以将热key复制多份,每个redis节点上存放一份,这样不存在请求的重定向使得压力全部定向到单个节点,能有效减轻单节点的压力。缺点是要进行复制的画只能在代码层手动操作,而且复制多份存放后会存在数据一致性问题。因此复制方案只能用于临时解决线上问题。

读写分离:

热key多数是读热key的操作,读写分离能保证从节点中数据的一致性,并且能轻松的横向扩展,能有效的分散压力,只是有点浪费资源,因为读写分离每个从节点上存的都是一样的数据。

多级缓存:

当热key数量不多,比如电商平台促销活动,热key都集中在少部分key上面,为此做读写分离增加机器性价比不高,使用多级缓存是个不错的解决方法。具体实现思路两种:

1.本地缓存,redis和业务服务器之间增加一个中间层(proxy),专门用来进行热key探查,这个proxy专门用来监视redis来统计达到预设的热key阈值的key,统计好后推送给业务服务器,让业务服务器存在本地缓存。

2.单独缓存,将proxy探查到的热key推送到单独的一个缓存热key的redis上去,如果扛不住,热key服务器再横向扩容,当然这个方案也是单独增加了服务器结点去处理热key的,除非保证系统中经常会有热key出现,不然的话使用本地缓存性价比更高。

使用多级缓存会存在一个问题,因为每次推送之间有时间间隔,缓存中的数据和redis中的数据不是呈现强一致性的,而是呈现最终一致性的。这种代价也是不得不接受的,在使用缓存的时候注意不要拿缓存做逻辑,只用来做查询即可。

相关推荐
一 乐2 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
卓怡学长2 小时前
w214基于jsp知道特产网
java·intellij-idea
步行cgn2 小时前
Spring 注解使用详解
java·spring
一条小小yu2 小时前
Spring IoC的理解
java·后端·spring
落魄实习生3 小时前
Agent Scope Java 2.x 系列【7】工具使用
java·开发语言·ai
旺仔学长 哈哈3 小时前
springboot钓鱼爱好者交流平台APP设计与实现
java·spring boot·mysql·充电桩管理系统
自强的小白4 小时前
核心功能(Service接口)
java·mybatis
乌暮5 小时前
深入理解 Java 泛型:把「万能盒子」用对、用稳
java·开发语言·后端·学习
大猫和小黄6 小时前
深入理解 Java Optional:从设计哲学到工程实战
java