首页 > 数据库 >Redis热点大Key的优化过程

Redis热点大Key的优化过程

时间:2022-12-20 21:31:38浏览次数:60  
标签:缓存 对象 数据 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...​

 

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


Redis热点大Key的优化过程_Redis

作者:​​翎野君​

标签:缓存,对象,数据,Redis,过滤,全量,Key,优化
From: https://blog.51cto.com/lingyejun/5956762

相关文章

  • Dockerfile优化
    Dockerfile优化Dockerfile文件优化$cat>Dockerfile<<EOFFROMnode:9.11.1-alpineasbuild-stageRUNmkdir-p/usr/src/appWORKDIR/usr/src/appCOPYpackage*.......
  • Redisson实现分布式锁剖析
    Redission实现分布式锁:Redission是什么?Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-MemoryDataGrid),它充分利用了Redis键值数据库提供的一系列优势,基于J......
  • 一步步优化JVM五:优化延迟或者响应时间
    本节的目标是做一些优化以满足对应用对延迟的需求。这次需要几个步骤,包括完善Java堆大小的配置,评估垃圾回收占用的时间和频率,也许还要尝试切换到不同的垃圾回收器,以及由于使......
  • 唯品会Redis cluster大规模生产实践经验
    嘉宾:陈群很高兴有机会给大家分享rediscluster的生产实践经验。目前在唯品会主要负责redis/hbase的运维和开发支持工作,也参与工具开发工作。Outline一、生产应用场景二、存......
  • 【Redis系列】- 有哪些情况会导致Redis阻塞
    集合的全量查询和聚合操作:比如keyshgenall等操作,时间复杂度是O(n),随着n的增大耗时会越大   bigkey删除:删除操作的本质是要释放键值对占用的内存空间,一下子释放了大量......
  • Scrapy-redis 源码分析 及 框架使用
     From:​​https://cuiqingcai.com/6058.html​​Scrapy-redisgithub:​​https://github.com/rmax/scrapy-redis​​​scrapy-redis分布式爬虫框集群版Scrapy-Redis:​​......
  • 【Redis系列】- 什么是缓存击穿、缓存穿透、缓存雪崩?
    背景我们在项目中大量使用Redis承接海量数据的冲击,但是使用过程中也会遇到一些特殊的情况,这个就是缓存击穿、缓存穿透、缓存雪崩。 缓存穿透问题 先来看一个......
  • 技术分享 | 优化 InnoDB 的主键
    作者:YvesTrudeau翻译:管长龙前言作为Percona的首席架构师,我的主要职责之一是对客户的数据库进行性能方面的优化,这使得工作复杂且非常有趣。在这篇文章中,我想讨论一个最重......
  • docker-compose 编排Net6项目,redis/mysql/nlog实战
    十年河东,十年河西,莫欺少年穷学无止境,精益求精1、新建net6webapi项目一个非常简单的net6项目,使用mysql数据库,redis做缓存   关于项目的搭建,这里不做说明,本篇主......
  • 从面试题入手,畅谈 Vue 3 性能优化
    前言今年又是一个非常寒冷的冬天,很多公司都开始人员精简。市场从来不缺前端,但对高级前端的需求还是特别强烈的。一些大厂的面试官为了区分候选人对前端领域能力的深度,经常......