缓存-缓存的使用与基本详解

1.缓存使用

为了系统性能的提升,我们一般都会将部分数据放入缓存中,加速访问。而db承担数据落盘工作。

哪些数据适合放入缓存?

  • 即时性、数据一致性要求不高的
  • 访问量大且更新频率不高的数据(读多,写少)

举例:

电商类应用,商品分类,商品列表等适合缓存并加一个失效时间(根据数据更新频率来定),后台如果发布了一个商品,买家需要5分钟才能看到新的商品一般还是可以接受的

2.本地缓存 

最简单的加入缓存

 

 吞吐量大大提升

这样的方式称作本地缓存

弊端 在单体应用没有问题,分布式项目问题如下

  1. 缓存不在同一个服务里,导致第一个查数据库得到缓存放入本地,然后又来一个请求负载均衡到第二个服务,没有缓存,导致又去查一遍数据库
  2. 假设一个数据库的数据修改了需要修改缓存,那么它只会更新操作数据库的那个服务,其他服务的缓存就会导致数据大量不一致。

分布式系统下应该使用分布式缓存

3.Redis缓存

1.导入依赖

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

2.application.yml

spring:redis:host: 192.168.232.209port: 6379database: 0

3.优化三级分类 

   @Autowiredprivate RedisTemplate<String,Object> redisTemplate;
//    private Map<String,Object> cacheMap = new HashMap<>();private static final String CATALOG_JSON="CATALOG_JSON";@Overridepublic Map<String, List<Catelog2Vo>> getCatalogJson() {Object result = redisTemplate.opsForValue().get(CATALOG_JSON);if(result!=null){return (Map<String, List<Catelog2Vo>>) result;}Map<String, List<Catelog2Vo>> map = getCatalogJsonFromDB();redisTemplate.opsForValue().set(CATALOG_JSON,map);return map;}public Map<String, List<Catelog2Vo>> getCatalogJsonFromDB() {//1.查出所有1级分类List<CategoryEntity> selectList = baseMapper.selectList(null);/*** 将数据库的多次查询变成一次*///2. 封装数据List<CategoryEntity> level1Category = selectList.stream().filter(s->s.getParentCid().equals(0L)).collect(Collectors.toList());Map<String, List<Catelog2Vo>> map = level1Category.stream().collect(Collectors.toMap(k -> k.getCatId().toString(), v -> {//1.每一个的一级分类,查到1级分类的所有二级分类List<CategoryEntity> categoryEntities = selectList.stream().filter(s->s.getParentCid().equals(v.getCatId())).collect(Collectors.toList());List<Catelog2Vo> catelog2VoList = categoryEntities.stream().map(c -> {Catelog2Vo catelog2Vo = new Catelog2Vo();catelog2Vo.setId(c.getCatId().toString());catelog2Vo.setName(c.getName());catelog2Vo.setCatalog1Id(v.getCatId().toString());List<CategoryEntity> categoryEntities1 = selectList.stream().filter(s->s.getParentCid().equals(c.getCatId())).collect(Collectors.toList());List<Catelog2Vo.Catelog3Vo> collect = categoryEntities1.stream().map(c3 -> {Catelog2Vo.Catelog3Vo catelog3Vo = new Catelog2Vo.Catelog3Vo();catelog3Vo.setId(c3.getCatId().toString());catelog3Vo.setName(c3.getName());catelog3Vo.setCatalog2Id(c.getCatId().toString());return catelog3Vo;}).collect(Collectors.toList());catelog2Vo.setCatalog3List(collect);return catelog2Vo;}).collect(Collectors.toList());return catelog2VoList;}));return map;}

4.进行压力测试

会有异常

1.第一种异常

 连接量太大

2.第二种异常

很重要 堆外内存溢出  OutOfDirectMemoryError

分析源码

 

 这是 

lettuce-core 老版本报的错  就是内存没有及时释放,导致内存泄漏,是新来的空间大于最大空间,就会抛出堆外内存溢出

新版本可以不用解决

  1. springboot2.0 以后默认使用lettuce作为操作 redis的客户端。它使用netty进行网络通信。
  2. lettuce 的bug导致netty 堆外内存溢出,-Xmx300m; netty如果没有指定堆外内存,默认是使用-Xms300m
  3. 可以通过 -Dio.netty.maxDirectMemory进行设置
  4. 但是不能只是用 -Dio.netty.maxDirectMemory进行设置
  5. 可以升级lettuce客户端版本解决
  6. 可以使用jedis

3.来整合jedis

没玩过,试试,虽然这个Bug新版本解决了,但是想多学一点就来整合一下

1.导入依赖 
 <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>

补充:lettuce、jedis操作redis的底层客户端。spring再次封装redisTemplate

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/42004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何配置 PostgreSQL 以实现高可用性和故障转移?

文章目录 一、高可用性和故障转移的概念&#xff08;一&#xff09;数据复制&#xff08;二&#xff09;监控和检测&#xff08;三&#xff09;快速切换 二、实现高可用性和故障转移的技术方案&#xff08;一&#xff09;流复制&#xff08;Streaming Replication&#xff09;&…

轻松创建对象——简单工厂模式(Java实现)

1. 引言 大家好&#xff0c;又见面了&#xff01;在上一篇文章中&#xff0c;我们通过Python示例介绍了简单工厂模式&#xff0c;今天&#xff0c;我们继续深入这个话题&#xff0c;用Java来实现简单工厂模式。 2. 什么是简单工厂模式 简单工厂模式&#xff08;Simple Facto…

idea部署war包成功,但是接口404

场景 项目结构 xxx-xxx-app xxx-xxx-service xxx-xxx-webappapp/webapp依赖service&#xff0c;service中写了各种api&#xff0c;先别管它合不合理&#xff0c;正式环境用webapp发布。 本地配置tomcat启动&#xff0c;但是发现每次部署成功&#xff0c;但是service中的接口…

Laravel模型事件完全指南:触发应用程序的动态行为

标题&#xff1a;Laravel模型事件完全指南&#xff1a;触发应用程序的动态行为 在Laravel框架中&#xff0c;模型事件提供了一种优雅的方式来处理Eloquent模型生命周期中的各种关键时刻。通过监听和响应这些事件&#xff0c;开发者可以自动化许多常见的任务&#xff0c;如日志…

【TB作品】脉搏测量,ATMEGA8单片机,Proteus仿真,ATmega8控制脉搏测量与显示系统

硬件组成&#xff1a; LCD1602脉搏测量电路&#xff08;带灯&#xff09;蜂鸣器报警按键设置AT24C02 功能&#xff1a; &#xff08;1&#xff09;LCD1602主页显示脉搏、报警上限、报警下限&#xff1b; &#xff08;2&#xff09;五个按键&#xff1a;按键1&#xff1a;切换设…

baomidou多数据源切换注解@DS没有效果

baomidou多数据源切换注解DS没有效果 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.1.1</version> </dependency> ##原因 方法上有Transaction…

Docker学习笔记(二)镜像、容器、仓库相关命令操作

一、docker镜像操作 列出镜像列表 我们可以使用 docker images 来列出本地主机上的镜像。 各个选项说明: REPOSITORY&#xff1a;表示镜像的仓库源 TAG&#xff1a;镜像的标签 IMAGE ID&#xff1a;镜像ID CREATED&#xff1a;镜像创建时间 SIZE&#xff1a;镜像大小 查…

Kubernetes 负载均衡器解决方案 MetalLB实践

Kubernetes 负载均衡解决方案 MetalLB实践 MetalLB 是一个用于在 Kubernetes 集群中提供外部 IP 地址的负载均衡器实现。 准备工作 1. 安装需知 安装 MetalLB 有一些前置条件&#xff1a; Kubernetesv1.13.0 或者更新的版本 集群中的 CNI 要能兼容 MetalLB&#xff0c;最新…

【算法 之快速排序 原理及案例】

快速排序&#xff08;Quick Sort&#xff09; 快速排序&#xff08;Quick Sort&#xff09;是一种非常高效的排序算法&#xff0c;它采用了分治&#xff08;Divide and Conquer&#xff09;的思想。快速排序的基本步骤是&#xff1a; 选择一个基准元素&#xff08;pivot&…

昇思25天学习打卡营第9天|静态图模式的深度剖析与应用指南

目录 背景介绍 动态图模式 静态图模式 静态图模式的使用场景 静态图模式开启方式 基于装饰器的开启方式 基于context的开启方式 静态图的语法约束 JitConfig配置选项 静态图高级编程技巧 背景介绍 AI 编译框架主要包含两种运行模式&#xff0c;即动态图模式与静态图模…

19C 单机文件系统安装文档

准备工作 1)查看系统版本、内核参数 more /etc/redhat-release more /etc/redflag-releaseuname -a2)查看当前系统是否配置了HugePages。在下面的查询中&#xff0c;HugePages的几个相关值都为0&#xff0c;表明当前未配值HugePages&#xff0c;其次可以看到该版本的大页大小为…

【数据结构】03.顺序表的应用——通讯录

本篇文章我们将使用顺序表来实现通讯录的增删查改功能。 代码如下&#xff1a; //Contact.h#pragma once#define NAME_MAX 30 #define GENDER_MAX 10 #define ADDRESS_MAX 100 #define TEL_MAX 12enum{Exit,Add,Del,Seek,Change,Show};//枚举类型&#xff0c;便于理解数字含义…

初学Spring之动态代理模式

动态代理和静态代理角色一样 动态代理的代理类是动态生成的 动态代理分为两大类&#xff1a; 基于接口的动态代理&#xff08;JDK 动态代理&#xff09;、基于类的动态代理&#xff08;cglib&#xff09; 也可以用 Java 字节码实现&#xff08;Javassist&#xff09; Prox…

Java之网络面试经典题(一)

目录 ​编辑 一.Session和cookie Cookie Session 二.HTTP和HTTPS的区别 三.浅谈HTTPS为什么是安全的&#xff1f; 四.TCP和UDP 五.GET和Post的区别 六.forward 和 redirect 的区别&#xff1f; 本专栏全是博主自己收集的面试题&#xff0c;仅可参考&#xff0c;不能相…

转发服务器实验

首先先克隆一个虚拟机并完成ip地址的修改 nmcli connection modify ens160 ipv4.addresses 192.168.209.128/24 nmcli connection modify ens160 ipv4.method manual nmcli connection modify ens160 connection.autoconnect yes nmcli connection up ens160 nmcli connection…

Java虚拟机(JVM)深入解析与性能调优

Java虚拟机&#xff08;JVM&#xff09;是Java语言的核心&#xff0c;它为Java程序提供了一个运行环境&#xff0c;使得Java程序具有跨平台的特性。深入理解JVM的工作原理对于编写高效的Java代码和进行性能调优至关重要。本文将详细介绍JVM的工作原理&#xff0c;包括内存模型、…

web系统更改静态文件后不生效的问题解决

当改了js或css文件后&#xff0c;需要手动清理浏览器缓存&#xff0c;更改的代码才生效的问题&#xff0c;可以通过对引用文件的地方添加版本号进行解决。 比如&#xff1a; <script src"js/js_admin/permission.js"></script> 添加版本号后&#xff…

强化学习编程实战-1-一个及其简单的强化学习实例(多臂赌博机)

1.1 多臂赌博机 一台拥有K个臂的机器&#xff0c;玩家每次可以摇动K个臂中的一个&#xff0c;摇动后&#xff0c;会吐出数量不等的金币&#xff0c;吐出金币的数量服从一定的概率分布&#xff0c;而且不同臂的概率分布不同。 多臂赌博机的问题是&#xff1a;假设玩家共有N次摇地…

WPF中Background=“{x:Null}“ 和 Transparent

WPF中关于背景透明和背景无 此时&#xff0c;我代码中是写的有有个控件&#xff0c;一个Border &#xff0c;一个TextBox &#xff0c;范围都是全屏这么大&#xff0c;可以输入TextBox 因为&#xff0c;当border没有设置背景的时候&#xff0c;实际上是&#xff1a; <Borde…

尚庭公寓——数据库设计

1. 数据的关系 一对一&#xff0c;一对多&#xff08;多对一&#xff09;&#xff0c;多对多 2. 实体关系模型 实体关系模型常用ER图&#xff08;enity relationship graph&#xff09;表示&#xff1b; 矩形表示实体&#xff08;类似Java中的对象&#xff0c;如学生就是一…