【二十六】springboot整合jedis和redisson布隆过滤器处理缓存穿透

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 【二十六】springboot整合jedis和redisson布隆过滤器处理缓存穿透


       本章来学习记录一下关于缓存三大典型问题其一的缓存穿透的基本解决方式:通过布隆过滤器以及设置null值

       为了实现这一demo,需要整合jedis和redisson,所以本文主要会从下面几个方面开始讲述:

  • springboot整合Jedis
  • springboot使用Redis的两种方式(Jedis和Redistemplate)
  • springboot整合Redission布隆过滤器
  • springboot使用布隆过滤器的四种方式(设置到redis内,手写,Redission,Guava)
  • 编写代码测试缓存穿透

一、什么是缓存穿透

       首先本文的目的就是学习怎么通过布隆过滤器解决缓存穿透,那么缓存穿透是什么呢,大致如下图。

       为了解决数据库的压力问题,引入了缓存这一东西,将某些数据存入缓存后,接口直接从缓存取值,从而减轻数据库的压力。当客户端访问的数据在缓存中不存在时,就会到数据库查询,查到了再存入缓存,而缓存击穿就是恶意攻击,一直访问数据库中不存在的数据,导致直接穿过缓存,每次都击中数据库。


二、怎么解决缓存穿透

       解决缓存穿透的方式可以通过布隆过滤网和空值设置法,本文会将两种方法都使用到。

1、布隆过滤器:可以理解为就是一个普通的过滤器拦截器,将数据通过add方法存入过滤器之后,通过它提供的contains方法判断是否存在某个值,返回值也是true或者false,详细的自己百度一下。他会有一定的误差(返回true,表示不一定存在;返回false,表示一定不存在),但是我认为解决缓存穿透可以不用考虑这个问题,因为只需要确认它一定不存在就可以了。具体使用时,在项目启动时可以查询数据库,将所有需要缓存的数据存入过滤器,每次接口调用时,通过它先判断一遍,存在后再走后面的逻辑(查缓存、查数据库)。

2、空值设置法:查询数据库时,若不存在该数据,设置一个过期时间短的缓存到redis,下次到缓存查询时就能查到该值,并直接返回对应的value值null,设置一个较短的过期时间是为了以防后面该值被误处理,一直查询处于空值,还有就是可能会出现大量的处于null值的缓存,占用缓存资源。

3、综上,本次demo的缓存穿透解决方式,如下(综合两种方式):


三、springboot怎么使用Redis

       上面已经讲了如何解决缓存穿透,这小节就介绍一下,一般springboot怎么使用redis呢?很简单,通常有两种方式,一种是RedisTemplate,一种是Jedis。

  • RedisTemplate:RedisTemplate是SpringDataRedis中对JedisApi的高度封装。
  • Jedis:Jedis是Redis官方推荐的面向Java的操作Redis的客户端。

       原生jedis效率优于redisTemplate。

       前面有一章已经整合过 redisTemplate方式使用redis了,感兴趣的可以看看。【七】springboot整合redis(超详细)_

        所以后面在这次demo中会使用jedis来操作redis。

四、springboot怎么使用布隆过滤器

       springboot使用布隆过期器也有多种方式,比如使用谷歌的Guava

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
</dependency>

        或者使用redis提供的redisson

 <dependency>
     <groupId>org.redisson</groupId>
     <artifactId>redisson</artifactId>
</dependency>

       本次demo将会集成redisson的方式使用布隆过滤器。

五、springboot整合Jedis

       整合Jedis的方式很简单,直接引入依赖,配置好连接就可以了,如下:

1、引入依赖

2、新建配置文件(反正是学习,将配置写死在代码内也行)

3、编写redis配置文件(关于jedis的,后面会将redisson的也写在这个配置文件,我为了简便,通用配置信息)

       通过ResourceBundle配合静态块,将配置信息读取到并设置到jedis连接池进行创建连接池。

PS:也可以不使用连接池,直接使用Jedis,但是那样的话,会每次连接都会创建新的Jedis对象,推荐使用连接池的方式,类似数据库的连接池。

       然后通过 Jedis jedis = jedisPool.getResource();就可以得到Jedis对象,就可以通过Jedis提供的Api方法进行redis的操作了。

六、springboot整合Redisson

       上面整合了Jedis,下面进行最后Redisson的整合,依旧是引入依赖,然后连接上缓存,再通过Redisson创建布隆过滤器即可。

1、引入依赖

2、修改redisConfig(上面创建的配置文件,新增redisson的连接,以及布隆过滤器的创建)

PS:文章最开始提过布隆过滤器是有误差率的,所有在创建时会有参数来控制这个误差率,

第一个参数代表大小,第二个参数代表容错率,具体的就不提了,百度学习吧。

再提一嘴,上述的bean要保证单例,要么自己实现或者交给spring管理就可以了,spring创建的bean默认是单例的。

六、准备demo所需

       本小结,介绍一下本次demo最后需要的准备,本章的ORM框架使用的是Mybatis-plus,前面也有讲过具体的使用【四】springboot整合mybatis-plus(超详细)

       所以需要创建mapper层等代码。

1、创建数据库表

CREATE TABLE `product` (
  `pid` int NOT NULL AUTO_INCREMENT,
  `productName` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  `price` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=253 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;

2、随便导入几百条数据

3、创建实体映射类

4、创建mapper层

5、创建项目初始化时将产品信息存入缓存和布隆过滤器的操作

       关于实现的InitializingBean接口,在前面的章节也有说过,【问题篇】springboot项目通过数据库限制实例端口号_

6、创建controller

       具体的处理流程就是前面贴的流程图的处理方式,最后一小节进行测试。


七、测试

       本次demo整合了swagger,所有直接通过swagger调用接口进行测试,前面有讲过如何整合swagger,【一】springboot整合swagger(超详细)_。

1、测试数据库、缓存 、布隆过滤器中都存在的数据。

布隆过滤器是二进制向量

可以看到走的是缓存。

2、测试数据库、缓存 、布隆过滤器中都不存在的数据。

控制台是空的,缓存和数据库都没走。

3、测试布隆过滤器中存在的数据,数据库、缓存不存在的数据(模拟原本存在的数据,被删除了)

模拟操作:启动服务后,将id为1的产品从数据库和缓存中删除。

会去缓存设置空值。

本次查询了数据库并缓存了一个null值。

当第二次请求时,查询id为1的产品时,如下:

会去查询缓存,不会再次查询数据库了。

其他的情况本章就不再测试了,感兴趣的兄弟可以自己试试,到此null值设置法和布隆过滤器的解决办法都测试出效果了。

相关实践学习
基于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
目录
相关文章
|
9天前
|
缓存 数据库 NoSQL
【后端面经】【缓存】35|缓存问题:怎么解决缓存穿透、击穿和雪崩问题?--主从切换方案
【5月更文挑战第16天】该方案提出了解决Redis缓存穿透、击穿和雪崩问题的策略。通过使用两个或多个互为备份的Redis集群,确保在单个集群故障时,另一个可以接管。在故障发生时,业务会与备用集群保持心跳检测,并根据业务重要性分批转移流量,逐步增加对备用集群的依赖,同时监控系统稳定性。对于成本敏感的小型公司,可以采用低成本的单机或小规模自建Redis备份。此方案强调渐进式流量转移,以保护系统免受突然压力冲击。
19 1
【后端面经】【缓存】35|缓存问题:怎么解决缓存穿透、击穿和雪崩问题?--主从切换方案
|
10天前
|
缓存 数据库 算法
【后端面经】【缓存】35|缓存问题:怎么解决缓存穿透、击穿和雪崩问题?---解决缓存击穿和雪崩、限流
【5月更文挑战第15天】本文介绍了如何解决缓存击穿和雪崩问题。对于缓存击穿,采用singleflight模式,确保即使热点数据导致大量请求未命中缓存,也只允许一个请求真正查询数据,其他请求等待其结果。对于缓存雪崩,解决方案是在设置过期时间时添加随机偏移量,避免所有数据同时过期。偏移量应与过期时间成正比。此外,限流也是一个重要策略,可以在服务层和数据库层实施,以限制请求流量,保护数据库免受高并发压力。
15 0
【后端面经】【缓存】35|缓存问题:怎么解决缓存穿透、击穿和雪崩问题?---解决缓存击穿和雪崩、限流
|
11天前
|
存储 缓存 NoSQL
【后端面经】【缓存】35|缓存问题:怎么解决缓存穿透、击穿和雪崩问题?---解决缓存穿透
【5月更文挑战第14天】解决缓存穿透问题有两种策略。一是回写特殊值,当数据不存在时,在缓存中存储特殊值以标记,避免下次重复查询数据库。但此方法可能被恶意请求利用,浪费内存。二是使用布隆过滤器,预先判断数据是否存在,减少无效数据库查询。布隆过滤器虽有假阳性可能,但概率低,可接受。此外,可先查缓存再查布隆过滤器,优化正常请求的效率。两种方式各有优劣,实际应用需根据场景选择。
22 3
|
11天前
|
缓存 数据库 NoSQL
【后端面经】【缓存】35|缓存问题:怎么解决缓存穿透、击穿和雪崩问题?---缓存穿透、击穿和雪崩
【5月更文挑战第13天】本文讨论了三种常见的缓存问题:穿透、击穿和雪崩。缓存穿透发生时,请求的数据既不在缓存也不在数据库,可能导致数据库崩溃。缓存击穿指数据仅存在于数据库,热点数据的大量未命中请求会压垮数据库。缓存雪崩则是大量缓存在同一时间过期,引发数据库瞬间压力过大。为应对这些问题,需了解Redis部署(如Cluster或Sentinel)、故障恢复策略,以及公司如何保护数据库。解决缓存问题的经验和预防措施是面试中的重要话题。
16 0
【后端面经】【缓存】35|缓存问题:怎么解决缓存穿透、击穿和雪崩问题?---缓存穿透、击穿和雪崩
|
11天前
|
缓存 监控 NoSQL
Redis经典问题:缓存穿透
本文介绍了缓存穿透问题在分布式系统和缓存应用中的严重性,当请求的数据在缓存和数据库都不存在时,可能导致数据库崩溃。为解决此问题,提出了五种策略:接口层增加校验、缓存空值、使用布隆过滤器、数据库查询优化和加强监控报警机制。通过这些方法,可以有效缓解缓存穿透对系统稳定性的影响。
111 3
|
11天前
|
缓存 NoSQL 搜索推荐
Redis缓存雪崩穿透等解决方案
本文讨论了缓存使用中可能出现的问题及其解决方案。首先,缓存穿透是指查询数据库中不存在的数据,导致请求频繁到达数据库。解决方法包括数据校验、缓存空值和使用BloomFilter。其次,缓存击穿是大量请求同一失效缓存项,可采取监控、限流或加锁策略。再者,缓存雪崩是大量缓存同时失效,引发数据库压力。应对措施是避免同一失效时间,分散缓存过期。接着,文章介绍了Spring Boot中Redis缓存的配置,包括缓存null值以防止穿透,并展示了自定义缓存过期时间的实现,以避免雪崩效应。最后,提供了在`application.yml`中配置不同缓存项的个性化过期时间的方法。
|
11天前
|
缓存 监控 数据库
分布式系统中缓存穿透问题与解决方案
在分布式系统中,缓存技术被广泛应用以提高系统性能和响应速度。然而,缓存穿透是一个常见而严重的问题,特别是在面对大规模请求时。本文将深入探讨缓存穿透的原因、影响以及一些有效的解决方案,以确保系统在面对这一问题时能够保持稳定和高效。
41 13
|
11天前
|
缓存 NoSQL Java
springboot业务开发--springboot集成redis解决缓存雪崩穿透问题
该文介绍了缓存使用中可能出现的三个问题及解决方案:缓存穿透、缓存击穿和缓存雪崩。为防止缓存穿透,可校验请求数据并缓存空值;缓存击穿可采用限流、热点数据预加载或加锁策略;缓存雪崩则需避免同一时间大量缓存失效,可设置随机过期时间。文章还提及了Spring Boot中Redis缓存的配置,包括缓存null值、使用前缀和自定义过期时间,并提供了改造代码以实现缓存到期时间的个性化设置。
|
11天前
|
编解码 NoSQL Java
Springboot框架使用redisson实现分布式锁
Redisson是官方推荐的Java Redis客户端,提供丰富的功能,包括默认的分布式锁支持。它可以无缝替代Spring Boot 2.x的Letture客户端,不影响原有RedisTemplate和Redis Repository的使用。集成包括spring-boot-starter-data-redis和redisson-spring-boot-starter,后者需排除默认的redisson-spring-data-23以匹配Spring Data Redis v.2.2.x。
|
11天前
|
缓存 NoSQL 搜索推荐
Redis缓存雪崩穿透等解决方案
本文讨论了缓存使用中的三个问题:缓存穿透、缓存击穿和缓存雪崩。为解决这些问题,提出了相应策略。对于缓存穿透,建议数据校验和缓存空值;缓存击穿可采用监控扩容、服务限流或加锁机制;缓存雪崩则需避免大量缓存同时过期,可设置随机过期时间。此外,文章还介绍了Spring Boot中Redis缓存配置,包括全局设置及自定义缓存过期时间的方法。