谷粒商城—缓存—缓存(151~156)

编程入门 行业动态 更新时间:2024-10-27 00:34:40

谷粒商城—<a href=https://www.elefans.com/category/jswz/34/1771061.html style=缓存—缓存(151~156)"/>

谷粒商城—缓存—缓存(151~156)

一.缓存使用:

            1)缓存 介绍: 
                    a:为了系统性能 的提升,会将 部分数据放入缓存中,可以加速访问,而 DB 只承担数据落盘工作。
                    b:哪些数据 适合放入缓存?
                                -1.及时性 / 数据一致性 要求不高的。
                                -2.访问量大且频率更新不高的数据(读多,写少)。

                    c:读模式 缓存使用 流程:( 图示 / 代码)
  



            2)整合 Redis: 
                    a:添加 POM 文件:

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

                    b:配置文件:
                                  a:Redis 配置类是 :RedisAutoConfiguration.class
                                  b:Redis 配置文件 可配置的 选项:RedisProperties.class
                                  c:写配置文件:application.yml:

spring:redis:host: 114.215.173.88port: 6379

                                  d:编写 测试类,进行 Redis 测试:

    @Autowiredprivate StringRedisTemplate stringRedisTemplate;@Testvoid contextLoads2() {ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();operations.set("hello", "workd : " + UUID.randomUUID().toString());String hello = operations.get("hello");System.out.println(hello);}


            3)优化 三级查询 业务,加入缓存功能: 
​​​​​​​                    a:Service 代码 优化:

    @Autowiredprivate StringRedisTemplate stringRedisTemplate;@Overridepublic PageUtils queryPage(Map<String, Object> params) {IPage<CategoryEntity> page = this.page(new Query<CategoryEntity>().getPage(params),new QueryWrapper<CategoryEntity>());return new PageUtils(page);}@Overridepublic List<CategoryVo> listWithTree() {//1.加入缓存逻辑ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();//2.从缓存中获取对象String listWithTree = operations.get("listWithTree");if (StringUtils.isEmpty(listWithTree)) {log.info("查询 数据库了。");//3.缓存中 没有,从数据库 查询出来List<CategoryVo> categoryVos = getCategoryVos();//4.把 查询 出来的 数据,放入缓存,方便下次查询。//   [序列化 与 反序列化]operations.set("listWithTree", JSON.toJSONString(categoryVos));return categoryVos;}//[序列化 与 反序列化]
//        return JSON.parseObject(listWithTree, new TypeReference<List<CategoryVo>>() { }log.info("直接 返回 了");List<CategoryVo> categoryVoList = JSON.parseArray(listWithTree, CategoryVo.class);return categoryVoList;}

​​​​​​​                    b:fastJson (List 和 JSON 互相转换):见 a



            4)加缓存后,压力测试(内存泄漏问题): 
​​​​​​​                    a:outofdirectmemoryerror 形成原因:
                                  a:SpringBoot 2.0 以后,默认使用 lettuce,作为 操作 redis 的客户端。它使用 netty 进行网络通信。
                                  b:lettuce 的 bug ,导致 netty 堆外 内存溢出。
​​​​​​​                    b:解决方法:
                                  a:升级 lettuce 客户端。
                                  b:将 lettuce 去除,换为 Jedis 连接 Redis。

        <!-- .springframework.boot/spring-boot-starter-data-redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion></exclusions></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId></dependency>


            4)高并发下,缓存失效的问题:()
​​​​​​​                    a:缓存 穿透:
                                 -1.概念:指 查询一个 一定不存在的 数据,由于缓存不命中,则会去数据库中查询,但是数据库也无此记录,没有将这次查询到的 null 写入缓存(写入一个标志),导致 这个不存在的数据,每次请求,都要到 数据库 中查询,失去了缓存的意义。
                                 -2.风险:利用不存在的 数据进行攻击,数据库 顺势压力增大。
                                 -3.解决:null 结果,也加入缓存中,并且加入 短暂过期时间。

​​​​​​​                    b:缓存击穿:(缓存雪崩的其中一个)
                                 -1.概念:对于 一些设置了 过期时间的 key,如果这些 key,可能会在 某些时间点,被超高并发访问,是一种 非常热点的数据。如果 这个 key ,在大量请求 进来的同时前 正好失效,那么这个 key 的数据查询,都会落到 数据库 上,我们称为 缓存击穿。
                                 -2.解决:加锁,大量 并发,只让一个人查询,其他人等待,查询到数据以后,数据存入缓存。释放锁,其他人获取到锁,先查缓存,就会有数据,不用去 查询 数据库。

​​​​​​​                    c:缓存雪崩:
                                 -1.概念:指 我们在设置 缓存时 的 key,采用了相同的过期时间,导致大量缓存,在某一时刻同时失效,请求全部转发到 数据库,数据库 瞬时压力过重,导致缓存雪崩。
                                 -2.解决:在设置 缓存时,在原有的失效时间基础上,增加一个随机值,比如 1~5 分钟随机,这样,每一个缓存过期时间的重复率就会降低,很难引发集体失效的事件。


            4)三级查询 业务,优化缓存:
​​​​​​​                    a:空结果缓存,解决 缓存穿透 问题。
​​​​​​​                    b:key 设置随机,过期时间,解决缓存雪崩问题。
​​​​​​​                    c:加锁,解决缓存击穿问题。(本地锁)

    private List<CategoryVo> getCategoryVos() {//加锁synchronized (this) {//再次判断缓存中是否有数据。有直接返回String listWithTree = stringRedisTemplate.opsForValue().get("listWithTree");if (!StringUtils.isEmpty(listWithTree)) {List<CategoryVo> categoryVoList = JSON.parseArray(listWithTree, CategoryVo.class);return categoryVoList;}//1.查出所有分类......//2.放缓存中。......//返回组装好的 三级分类树return collect;}}



        4)本地锁在 分布式情况下 的问题
​​​​​​​                    a:复制 gulimail-product 项目,启动多个,并修改端口( --server.port=10002 )
​​​​​​​                    b:多个服务,每个服务都会查询 1 次 数据库,本地锁 锁不住。




 

三.Spring Cache 缓存 框架

        1)Spring Cache 简介:

                 1)注解介绍:
                                  a:@Cacheable:触发​​缓存填充。
                                  b:@CacheEvict:触发​​缓存逐出。
                                  c:@CachePut: 在不干扰方法执行的情况下更新缓存。
                                  d:@Caching:  重新组合要在一个方法上应用的多个缓存操作。
                                  e:@CacheConfig:在类级别共享一些与缓存相关的常见设置。
                 2):
 

        2)整合 Spring Cache,简化缓存开发 :

                 1)添加 redis,cache 依赖:

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency>

                 1)写 配置文件:
                                  a:@

更多推荐

谷粒商城—缓存—缓存(151~156)

本文发布于:2023-07-28 20:53:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1310116.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:缓存   谷粒   商城

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!