Java缓存理解

news2024/11/24 4:32:09

bc4596186e8c402a8161f81f9050dcfb.jpg

 

 

CPU占用:如果你有某些应用需要消耗大量的cpu去计算,比如正则表达式,如果你使用正则表达式比较频繁,而其又占用了很多CPU的话,那你就应该使用缓存将正则表达式的结果给缓存下来。

数据库IO性能:如果发现有大量数据需要频繁查询使用,或者某些数据不会频繁变更时,为了提高数据库IO性能,可以使用缓存

缓存定义

 

所谓缓存,就是将程序或系统经常要调用的对象存在内存中,一遍其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。

缓存主要可分为二大类:

通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;

内存缓存,也就是创建一个静态内存区域,将数据存储进去,例如我们B/S架构的将数据存储在Application中或者存储在一个静态Map中。

本地缓存

 

所谓的本地缓存是相对于网络而言的(包括集群,数据库访问等)

在系统中,有些数据,数据量小,但是访问十分频繁(例如国家标准行政区域数据或者一些数据字典等),针对这种场景,需要将数据搞到应用的本地缓存中,以提升系统的访问效率,减少无谓的数据库访问(数据库访问占用数据库连接,同时网络消耗比较大)

但是有一点需要注意,就是缓存的占用空间以及缓存的失效策略。

分布式/集群缓存定义

 

传统单机缓存概念的一个延伸,用于表示能跨越多台服务器,同时具有可扩展性的缓存。说白了,就是将本地缓存数据存储到远程可集群的缓存载体上,利用网络进行数据交换的一种缓存方式

常用集群载体:Redis;Memcached

多级缓存

 

定义:系统中使用多种缓存(本地缓存及分布式缓存)技术对数据进行缓存,应用数据时,按照优先级(先本地,后分布式)对数据进行依次读取,如果所有缓存中都无数据,则对数据库进行数据读写,并将取到的数据依次(先分布式,后本地)进行缓存更新

为什么使用多级缓存技术(以一级缓存L1(Caffeine)和二级缓存L2(Redis)举例)

如果只有L1,那么在系统重新部署后,缓存数据全部消失;

如果只要L2,使用Redis,很多系统都会使用云服务,这时访问Redis会有一定的网络I/O以及序列化反序列化,虽然性能很高但是其终究没有本地内存L1快

多级缓存常用技术

 

利用Caffeine做一级缓存,Redis作为二级缓存。

首先去Caffeine中查询数据,如果有直接返回。如果没有则进行第2步。

再去Redis中查询,如果查询到了返回数据并在Caffeine中填充此数据。如果没有查到则进行第3步。

最后去Mysql中查询,如果查询到了返回数据并在Redis,Caffeine中依次填充此数据。

对于Caffeine的缓存,如果有数据更新,只能删除更新数据的那台机器上的缓存,其他机器只能通过超时来过期缓存,超时设定可以有两种策略

设置成写入后多少时间后过期

设置成写入后多少时间刷新

缓存更新

 

先删除缓存,再更新数据库。

这个操作有一个比较大的问题,在对缓存删除完之后,有一个读请求,这个时候由于缓存被删除所以直接会读库,读操作的数据是老的并且会被加载进入缓存当中,后续读请求全部访问的老数据。

先更新数据库,再删除缓存(推荐)

有一个数据此时是没有缓存的,所以查询请求会直接落库,更新操作在查询请求之后,但是更新操作删除数据库操作在查询完之后回填缓存之前,就会导致我们缓存中和数据库出现缓存不一致,但是这个问题几率特别小。

为什么要删除缓存,而不是更新缓存

你可以想想当有多个并发的请求更新数据,你并不能保证更新数据库的顺序和更新缓存的顺序一致,那就会出现数据库中和缓存中数据不一致的情况。所以一般来说考虑删除缓存。

缓存坑货三剑客

 

缓存穿透

解释:缓存穿透是指查询的数据在数据库是没有的,那么在缓存中自然也没有,所以,在缓存中查不到就会去数据库取查询,这样的请求一多,那么我们的数据库的压力自然会增大

解决方案:

约定:对于返回为NULL的依然缓存,对于抛出异常的返回不进行缓存,注意不要把抛异常的也给缓存了。采用这种手段的会增加我们缓存的维护成本,需要在插入缓存的时候删除这个空缓存,当然我们可以通过设置较短的超时时间来解决这个问题。

制定一些规则过滤一些不可能存在的数据,小数据用BitMap,大数据可以用布隆过滤器,比如你的订单ID 明显是在一个范围1-1000,如果不是1-1000之内的数据那其实可以直接给过滤掉。

缓存击穿

解释:对于某些key设置了过期时间,但是其是热点数据,如果某个key失效,可能大量的请求打过来,缓存未命中,然后去数据库访问,此时数据库访问量会急剧增加。

解决方案:

加分布式锁:加载数据的时候可以利用分布式锁锁住这个数据的Key,在Redis中直接使用setNX操作即可,对于获取到这个锁的线程,查询数据库更新缓存,其他线程采取重试策略,这样数据库不会同时受到很多线程访问同一条数据。

异步加载:由于缓存击穿是热点数据才会出现的问题,可以对这部分热点数据采取到期自动刷新的策略,而不是到期自动淘汰。淘汰其实也是为了数据的时效性,所以采用自动刷新也可以。

缓存雪崩

解释:缓存雪崩是指缓存不可用或者大量缓存由于超时时间相同在同一时间段失效,大量请求直接访问数据库,数据库压力过大导致系统雪崩。

解决方案:

增加缓存系统可用性,通过监控关注缓存的健康程度,根据业务量适当的扩容缓存。

采用多级缓存,不同级别缓存设置的超时时间不同,及时某个级别缓存都过期,也有其他级别缓存兜底。

缓存的过期时间可以取个随机值,比如以前是设置10分钟的超时时间,那每个Key都可以随机8-13分钟过期,尽量让不同Key的过期时间不同。

缓存监控

 

很多人对于缓存的监控也比较忽略,基本上线之后如果不报错然后就默认他就生效了。但是存在这个问题,很多人由于经验不足,有可能设置了不恰当的过期时间,或者不恰当的缓存大小导致缓存命中率不高,让缓存就成为了代码中的一个装饰品。所以对于缓存各种指标的监控,也比较重要,通过其不同的指标数据,我们可以对缓存的参数进行优化,从而让缓存达到最优化

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

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

相关文章

基于YOLOv8和WiderFace数据集的人脸目标检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要:基于YOLOv8和WiderFace数据集的人脸目标检测系统可用于日常生活中检测与定位人脸目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测算…

数据结构(C语言版)概念、数据类型、线性表

数据结构(C语言)基本概念 数据的基本单位 数据的基本单位是位(bit)和字节(byte)。位是最小的存储单位,它可以表示一个二进制的0或1。字节由8个位组成,用于表示一个字符或数字。在计…

STM32 Nucleo-144开发板开箱bring-up

文章目录 1. 开篇2. 开发环境搭建2.1 下载官方例程2.2 ST-Link安装 3. STM32F446ZE demo工程3.1 STM32F446ZE简介3.2 跑个demo试一试 1. 开篇 最近做项目,用到STM32F446ZET6这款MCU,为了赶进度,前期软件需要提前开发,于是在某宝买…

基于FPGA的RGB图像转Ycbcr实现,包括tb测试文件以及MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 将FPGA的数据导入到matlab进行显示 2.算法运行软件版本 Vivado2019.2 matlab2022a 3.部分核心程序 timescale 1ns / 1ps // // Company: // E…

企业微信后台管理-关联小程序、H5/web

企业微信后台管理-小程序、web 应用-关联小程序应用-绑定h5(web页面的app)企业微信-工作台 应用-关联小程序 企业微信后台管理地址,管理员扫码登录后台管理,找到应用管理-自建-创建应用/小程序。 填写项目相关信息之后,如下图。 点击关联小…

Cpp/Qtday030908cpp基础

目录 目录 自行封装一个栈的类,包含私有成员属性:栈的数组、记录栈顶的变量 成员函数完成:构造函数、析构函数、拷贝构造函数、入栈、出栈、清空栈、判空、判满、获取栈顶元素、求栈的大小 头文件:stack.h 源文件: stack.cp…

数据结构之队列的实现(附源码)

目录 一、队列的概念及结构 二、队列的实现 拓展:循环队列 三、初学的队列以及栈和队列结合的练习题 一、队列的概念及结构 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(Fi…

jmeter 线程组 Open Model Thread Group 阶梯式压测、高峰流量压测

简介 Open Model Thread Group 是5.4.1 版本中引入的一个实验性线程组,可以弹性模拟负载测试。例如设置多个线程模式,再根据这些线程模式调整不同的并发数、暂停时间。由于Open Model Thread Group 是一个实验性线程组,可能会存在一些限制和不…

英语单词(1)

1.void:空的 2.main:主要的 3.class:类 4.system:系统 5.out: 输出 6.print:打印 7.public:公共的,公用的 8.static:静态的,静止的 9.oracle:甲骨文公司 10.eclipse: java编程语言

javascritp如何判断是从刷新(重新加载)、正常打开(或链接打开)、还是从浏览器回退进入页面的

重点先下另外一个知识点: 当我们的Web站点采用主体页面的iframe导航各个子页面(浏览器地址保持不变)的情况,如果我们希望每次iframe中打开的新的子页面,也都能够像在不采用iframe的情况那样,后续能够在浏览…

leetcode:58. 最后一个单词的长度

题目: 函数原型: int lengthOfLastWord(char * s) 解析: 求最后一个单词的长度,我们有两种思路 第一种思路: 逆向求,先设置一个字符串下标index,定位到最后一个单词的最后一个字符。再一个设置长…

【web开发】4.JavaScript与jQuery

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、JavaScript与jQuery二、JavaScript常用的基本功能1.插入位置2.注释3.变量4.数组5.滚动字符 三、jQuery常用的基本功能1.引入jQuery2.寻找标签3.val、text、appe…

CSP-J初赛复习大题整理笔记

本篇全是整理&#xff0c;为比赛准备. 在这里插入代码片 #include<cstdio> using namespace std; int n, m; int a[100], b[100];int main() {scanf_s("%d%d", &n, &m);for (int i 1; i < n; i)a[i] b[i] 0;//将两个数组清0&#xff0c;这…

Django Form实现表单使用及应用场景

首先需要定义一个使用场景&#xff1a; 音乐网站的前端部分可以添加上传歌手的单曲&#xff0c; 这个添加页面就使用django form表单来实现。 目录 数据表内容 歌手表及表模型 单曲表及表模型 演示表单使用 设置路由 创建form.py 视图实例化表单类 模板使用表单对象 表…

个人用户怎么免费使用电子签章平台,制作能在手机上双方都可以签字的租房合同?

环境 苹果11Pro手机 微信小程序 腾讯电子签 PDF版租房合同 问题描述 最近租房要续签合同&#xff0c;房东在外地&#xff0c;怎么免费使用有规范的合同电子签约平台制作电子签章&#xff0c;双方都能在手机上签合同&#xff0c;完成线上签约 解决方案 1.首先打开微信在搜…

【面试经典150 | 双指针】验证回文串

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;筛选判断方法二&#xff1a;原地判断 知识回顾回文串双指针字符串操作 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分…

【数据结构】二叉树的顺序结构实现及时间复杂度计算(二)

目录 一&#xff0c;二叉树的顺序结构实现 1&#xff0c;二叉树的顺序结构 2&#xff0c;堆的概念及结构 3&#xff0c;堆的接口实现 1&#xff0c;堆的创建 2&#xff0c;接口函数 3&#xff0c;初始化 4&#xff0c;销毁 5&#xff0c;是否增容 6&#xff0c;交换数据…

Redis基础详解

目录 一、概述 redis作用 redis特性 二、Redis基础知识 为什么Redis是单线程的&#xff1f; Redis的高并发和快速原因&#xff1f; Redis6.0 之后为何引入了多线程&#xff1f; 三、Redis五大数据类型&#xff0c;三种特殊数据类型 启动Redis Redis-Key String&#…

UMA 2 - Unity Multipurpose Avatar☀️三.给UMA设置默认服饰Recipes

文章目录 🟥 项目基础配置🟧 给UMA配置默认服饰Recipes🟨 设置服饰Recipes属性🟥 项目基础配置 将 UMA_DCS 预制体放到场景中创建空物体,添加DynamicCharacterAvatar 脚本,选择 HumanMaleDCS作为我们的基本模型配置默认Animator 🟧 给UMA配置默认服饰Recipes 服饰Re…

【web开发】5.Mysql及python代码执行数据库操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、MYSQL二、MySQL管理查看已有数据库创建数据库删除数据库进入数据库创建表删除表展示表的行列插入数据查看表中的数据删除数据修改数据 三、python代码执行数据库…