今天给大家介绍一下如何在springboot中解决redis的缓存穿透、缓存击穿、缓存雪崩的问题。
缓存穿透什么是缓存穿透缓存穿透指的是一个缓存系统无法缓存某个查询的数据,从而导致这个查询每一次都要访问数据库。
常见的redis缓存穿透场景包括:
查询一个不存在的数据:攻击者可能会发送一些无效的查询来触发缓存穿透。查询一些非常热门的数据:如果一个数据被访问的非常频繁,那么可能会导致缓存系统无法处理这些请求,从而造成缓存穿透。查询一些异常数据:这种情况通常发生在数据服务出现故障或异常时,从而造成缓存系统无法访问相关数据,从而导致缓存穿透。如何解决我们可以使用guava在内存中维护一个布隆过滤器。具体步骤如下:
添加guava和redis依赖: com.google.guava guava 29.0-jre org.springframework.boot spring-boot-starter-data-redis创建一个bloomfilterutil类,用于在缓存中维护bloom filter。public class bloomfilterutil { // 布隆过滤器的预计容量 private static final int expectedinsertions = 1000000; // 布隆过滤器误判率 private static final double fpp = 0.001; private static bloomfilter bloomfilter = bloomfilter.create(funnels.stringfunnel(charset.defaultcharset()), expectedinsertions, fpp); /** * 向bloom filter中添加元素 */ public static void add(string key){ bloomfilter.put(key); } /** * 判断元素是否存在于bloom filter中 */ public static boolean mightcontain(string key){ return bloomfilter.mightcontain(key); }}在controller中查询数据时,先根据请求参数进行bloom filter的过滤@autowiredprivate redistemplate缓存击穿什么是缓存击穿缓存击穿指的是在一些高并发访问下,一个热点数据从缓存中不存在,每次请求都要直接查询数据库,从而导致数据库压力过大,并且系统性能下降的现象。
缓存击穿的原因通常有以下几种:
缓存中不存在所需的热点数据:当系统中某个热点数据需要被频繁访问时,如果这个热点数据最开始没有被缓存,那么就会导致系统每次请求都需要直接查询数据库,造成数据库负担。缓存的热点数据过期:当一个热点数据过期并需要重新缓存时,如果此时有大量请求,那么就会导致所有请求都要直接查询数据库。如何解决主要思路 : 在遇到缓存击穿问题时,我们可以在查询数据库之前,先判断一下缓存中是否已有数据,如果没有数据则使用redis的单线程特性,先查询数据库然后将数据写入缓存中。
添加redis依赖 org.springframework.boot spring-boot-starter-data-redis在controller中查询数据时,先从缓存中查询数据,如果缓存中无数据则进行锁操作@autowiredprivate redistemplate redistemplate;@getmapping(/user/{id})public user getuserbyid(@pathvariable long id){ // 先从缓存中获取值 string userkey = user_+id.tostring(); user user = (user) redistemplate.opsforvalue().get(userkey); if(user == null){ // 查询数据库之前加锁 string lockkey = lock_user_+id.tostring(); string lockvalue = uuid.randomuuid().tostring(); try{ boolean lockresult = redistemplate.opsforvalue().setifabsent(lockkey, lockvalue, 60, timeunit.seconds); if(lockresult != null && lockresult){ // 查询数据库 user = userrepository.findbyid(id).orelse(null); if(user != null){ // 将查询到的数据加入缓存 redistemplate.opsforvalue().set(userkey, user, 300, timeunit.seconds); } } }finally{ // 释放锁 if(lockvalue.equals(redistemplate.opsforvalue().get(lockkey))){ redistemplate.delete(lockkey); } } } return user;}缓存雪崩什么是缓存雪崩指缓存中大量数据的失效时间集中在某一个时间段,导致在这个时间段内缓存失效并额外请求数据库查询数据的请求大量增加,从而对数据库造成极大的压力和负荷。
常见的redis缓存雪崩场景包括:
缓存服务器宕机:当缓存服务器宕机或重启时,大量的访问请求将直接命中数据库,并在同一时间段内导致大量的数据库查询请求,从而将数据库压力大幅提高。缓存数据同时失效:在某个特定时间点,缓存中大量数据的失效时间集中在一起,这些数据会在同一时间段失效,并且这些数据被高频访问,将导致大量的访问请求去查询数据库。缓存中数据过期时间设计不合理:当缓存中的数据有效时间过短,且数据集中在同一时期失效时,就容易导致大量的请求直接查询数据库,加剧数据库压力。波动式的访问过程:当数据的访问存在波动式特征时,例如输出某些活动物品或促销商品时,将会带来高频的查询请求访问,导致缓存大量失效并产生缓存雪崩。如何解决在遇到缓存雪崩时,我们可以使用两种方法:一种是将缓存过期时间分散开,即为不同的数据设置不同的过期时间;另一种是使用redis的多级缓存架构,通过增加一层代理层来解决。具体步骤如下:
添加相关依赖 org.springframework.boot spring-boot-starter-data-redis net.sf.ehcache ehcache 2.10.6在application.properties中配置ehcache缓存spring.cache.type=ehcache创建一个cacheconfig类,用于配置ehcache:@configuration@enablecachingpublic class cacheconfig { @bean public ehcachecachemanager ehcachecachemanager(cachemanager cm){ return new ehcachecachemanager(cm); } @bean public cachemanager ehcachemanager(){ ehcachemanagerfactorybean cmfb = new ehcachemanagerfactorybean(); cmfb.setconfiglocation(new classpathresource(ehcache.xml)); cmfb.setshared(true); return cmfb.getobject(); }}在ehcache.xml中添加缓存配置 在controller中查询数据时,先从ehcache缓存中获取,如果缓存中无数据则再从redis缓存中获取数据@autowiredprivate redistemplate以上就是使用springboot时如何解决redis的缓存穿透、缓存击穿、缓存雪崩的常用方法。
这款24串锂电池的国产BMS AFE模拟前端芯片精度速率值得推荐
凭区块链恐怕无法立即的增进客户对贵公司的信任
新型智能试妆镜,智能化妆领域的新产品
梯度多云管理平台通过移动云ECSC生态认证
对美国关税征收中国采取措施,贸易反击战打击美国高端半导体公司
如何在SpringBoot中解决Redis的缓存穿透等问题
理想L9 Max正式发布,超强动力系统配合大额购车优惠,售价45.98万元
变频器控制柜接线图及安装方法
2017年值得关注的人工智能七个热门趋势
基于Go的缓存实现方法
分享一个电谐波图形均衡器的示意图
传Intel将发布三款Gulftown核心六核桌面处理器
什么是芯片封装?有哪些作用?
The MathWorks推出新产品Simulink PLC
从铁氧体到电源,TDK多重组合拳出击电子市场
华为mate9怎么样?经典永不“褪色”华为mate9优缺点!
魅族手环专利申请曝光 或亮相魅蓝note新品发布会
c语言static的作用
食品亚硝酸盐快速检测仪的相关功能介绍
人工智能和MEMS之间的完美结合