Redis热点大Key的优化过程

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis热点大Key的优化过程

概念介绍

热点Key

产生的背景

用户消费的数据远大于生产的数据(热卖商品、热点新闻、热点评论、热门明星直播)。

对于电商网站中,我们经常可以会遇到热门商品的抢购或者秒杀场景以及事先经过广告投放等措施进行定向引流,这样就会导致某个热卖商品在短时间内涌入大量流量。

比如,双十一期间某些热门商品的降价促销,当这其中的某一件商品被数万次点击浏览或者购买时,会形成一个较大的需求量,这种情况下就会造成热点问题。

导致的问题及解决方案

热点Key产生问题的原因

请求到的分片过于集中,超过单台Server的性能极限。

在服务端读数据进行访问时,往往会对数据进行分片切分。此过程中会在某一主机Server上对相应的Key进行访问,当访问超过Server极限时,就会导致热点 Key 问题的产生。

热点Key的危害

  • 流量集中,达到物理网卡上限。
  • 请求过多,缓存分片服务被打垮。
  • DB 击穿,引起业务雪崩。

解决方式

  • 服务端缓存:即将热点数据缓存至服务端的内存中。
  • 备份热点Key:即将热点Key+随机数,随机分配至Redis其他节点中。这样访问热点key的时候就不会全部命中到一台机器上了。

大Key

Redis使用过程中经常会有各种大key的情况, 比如单个简单的key存储的value很大。

由于redis是单线程运行的,如果一次操作的value很大会对整个redis的响应时间造成负面影响,导致IO网络拥塞。

解决方案

将整存整取的大对象,分拆为多个小对象。可以尝试将对象分拆成几个key-value, 使用multiGet获取值,这样分拆的意义在于分拆单次操作的压力,将操作压力平摊到多个redis实例中,降低对单个redis的IO影响;

一次实战优化过程

问题简介

在电商网站的一次营销事件中,通过相关的引流操作,将大量流量在指定时间引流到了商品抢购页面,在抢购页中涉及到的几个后台接口,其中有一两个都会去查商品信息。

在商品模块对外暴露了一个对条件查询的接口,在上述的场景下就会短时间高频次的调用这个接口。

根据这个场景发现,商品数据,在活动期间会有很大的访问量,这是一个热点Key。另外由于前期错误的设置导致了这个热点Key又是一个大Key。

所以我们的优化过程就是按照如果解决掉热点Key和大Key的这两个问题进行的。之前并没有上述的概念,都是摸着石头过河,渐渐地思路才清晰起来。

解决过程

第一版

直接按条件查询数据库。

public List<ReturnObject> version1(QueryCriterionDto queryDto) {
    // 1.直接按照条件查询数据库
    // 2.将查询到的结果返回
}

第二版

将全量数据缓存到Redis中,查出数据后再进行过滤返回。

public List<ReturnObject> version2(QueryCriterionDto queryDto) {
    // 1.先尝试从缓存中查询全量数据
    // 2.如果不存在,则从数据库中把全量数据出,并缓存到Redis中
    // 3.对全量数据进行过滤筛选
    // 4.返回最终的结果
}

第三版:

仍然将全量数据缓存到Redis中,但是只缓存必要的数据,比如过滤条件,从缓存中拿出全部的数据后,进行过滤后列出需要返回的对象唯一id,再根据这一批唯一id去缓存中查单个的对象出来,最后拼成List返回。

public List<ReturnObject> version3(QueryCriterionDto queryDto) {
    // 1.先尝试从缓存中查询全量数据(这里的全量数据指的不是ReturnObject,而是另外一个只用于过滤筛选的简单对象)
    // 2.如果不存在,则从数据库中把全量数据出,转成简单对象,并缓存到Redis中
    // 3.简单对象中包含所有的过滤条件,过滤后得到一组最终的idList(每个id在缓存中对应一个ReturnObject)
    // 4.根据上面得到的idList,然后循环get取出最后的返回结果
}

第四版

将每次的获取单个对象的get操作,调整成mget这样就可以一次操作取出多个对象出来,然后再跟查询的keys比较一下size,如果少的话,再尝试从库中查一次,把少的数据补上。

public List<ReturnObject> version4(QueryCriterionDto queryDto) {
    // 1.先尝试从缓存中查询全量数据(这里的全量数据指的不是ReturnObject,而是另外一个只用于过滤筛选的简单对象)
    // 2.如果不存在,则从数据库中把全量数据出,转成简单对象,并缓存到Redis中
    // 3.简单对象中包含所有的过滤条件,过滤后得到一组最终的idList(每个id在缓存中对应一个ReturnObject)
    // 4.对上面得到的idList进行分组比如每50个keys作为一组,然后使用multiGet一次获取50个对象,从而降低redis调用次数
    // 5.针对从redis中没有取到的对象,再尝试从库中查询,进行填补
    // 6.返回最终的对象
}

 

参考文章:

https://cloud.tencent.com/dev...

https://blog.csdn.net/youanyy...

https://segmentfault.com/a/11...

 

如果对您有帮助,请不要忘了给翎野君点赞。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
26天前
|
存储 消息中间件 NoSQL
Redis数据类型详解:选择合适的数据结构优化你的应用
Redis数据类型详解:选择合适的数据结构优化你的应用
|
1月前
|
缓存 监控 NoSQL
【Redis性能瓶颈揭秘】「调优系列」深入分析热Key的排查策略和解决方案
【Redis性能瓶颈揭秘】「调优系列」深入分析热Key的排查策略和解决方案
214694 8
|
1月前
|
存储 缓存 NoSQL
【Redis】Redis魔法:揭秘Key的自动消失术——过期删除机制解析
【Redis】Redis魔法:揭秘Key的自动消失术——过期删除机制解析
132 0
|
2月前
|
存储 NoSQL 5G
redis优化编码之字符串
Redis数据结构之字符串
42 2
redis优化编码之字符串
|
3天前
|
存储 NoSQL Redis
【Redis】Redis如何实现key的过期删除
【Redis】Redis如何实现key的过期删除
|
3天前
|
存储 缓存 NoSQL
Redis多级缓存指南:从前端到后端全方位优化!
本文探讨了现代互联网应用中,多级缓存的重要性,特别是Redis在缓存中间件的角色。多级缓存能提升数据访问速度、系统稳定性和可扩展性,减少数据库压力,并允许灵活的缓存策略。浏览器本地内存缓存和磁盘缓存分别优化了短期数据和静态资源的存储,而服务端本地内存缓存和网络内存缓存(如Redis)则提供了高速访问和分布式系统的解决方案。服务器本地磁盘缓存因I/O性能瓶颈和复杂管理而不推荐用于缓存,强调了内存和网络缓存的优越性。
21 1
|
1天前
|
存储 缓存 NoSQL
使用Redis+AOP优化查询性能
使用Redis+AOP优化查询性能
8 0
|
22天前
|
NoSQL Shell Redis
批量迁移redis实例的key
批量迁移redis实例的key
|
1月前
|
存储 缓存 NoSQL
探索Redis的多样应用场景:加速和优化现代应用
探索Redis的多样应用场景:加速和优化现代应用
34 2
|
1月前
|
缓存 NoSQL Java
【九】springboot整合redis实现启动服务时热点数据保存在全局和缓存
【九】springboot整合redis实现启动服务时热点数据保存在全局和缓存
45 0