Java 缓存机制与缓存失效

在分布式系统中,缓存 是提高系统性能、减轻数据库压力的常用技术。合理的缓存策略不仅能提升响应速度,还能节省资源。不过,缓存并不是万能的,缓存失效 是开发中必须考虑的问题。如果处理不好,可能会导致数据不一致或性能下降。

本文将介绍 Java 缓存机制 的基本原理,结合 Redis、Ehcache 等框架的应用,深入探讨缓存的常见策略和缓存失效的处理方法。


在这里插入图片描述

一、缓存的基本原理

缓存的核心是用空间换时间,即通过预先存储一些结果数据,避免重复计算或数据库查询,从而加快响应速度。缓存的使用可以分为三个步骤:

  1. 查询缓存:首先从缓存中查找数据,如果缓存命中,直接返回结果。
  2. 更新缓存:如果缓存未命中,查询数据库或进行计算,得到结果后更新缓存。
  3. 缓存失效:当数据发生变化或缓存过期时,删除缓存中的旧数据。

二、Java 缓存框架介绍

缓存框架适用场景特点常用功能
Ehcache本地缓存轻量级,支持内存和磁盘TTL、TTI、LRU 缓存失效策略
Redis分布式缓存、高并发支持多种数据结构,高性能数据持久化、过期时间、分布式锁、Pub/Sub

1. Ehcache

Ehcache 是一个轻量级的 Java 缓存框架,支持内存缓存和磁盘缓存,可以集成到 Spring 等框架中,应用于本地缓存。

代码示例:
<!-- Maven 依赖 -->
<dependency><groupId>org.ehcache</groupId><artifactId>ehcache</artifactId><version>3.8.1</version>
</dependency>

Ehcache 配置文件 ehcache.xml:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"><cache name="userCache"maxEntriesLocalHeap="1000"timeToLiveSeconds="300"timeToIdleSeconds="300"></cache>
</ehcache>

Java 使用 Ehcache:

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;public class EhcacheExample {public static void main(String[] args) {CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(true);Cache<String, String> cache = cacheManager.createCache("userCache",CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class));// 缓存使用示例cache.put("userId_123", "John Doe");String user = cache.get("userId_123");System.out.println("User: " + user);cacheManager.close();}
}

Ehcache 的特点

  • 支持 内存+磁盘 的存储方案。
  • 可配置 TTL(Time to Live)TTI(Time to Idle) 来控制缓存的过期。

2. Redis 作为缓存

Redis 是最常用的分布式缓存框架,支持多种数据结构(如字符串、列表、哈希等),并且可以配置持久化机制,防止缓存数据丢失。

使用 Redis 作为缓存:
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;@Service
public class RedisCacheService {private final RedisTemplate<String, Object> redisTemplate;public RedisCacheService(RedisTemplate<String, Object> redisTemplate) {this.redisTemplate = redisTemplate;}public void putValue(String key, Object value) {redisTemplate.opsForValue().set(key, value);}public Object getValue(String key) {return redisTemplate.opsForValue().get(key);}public void deleteValue(String key) {redisTemplate.delete(key);}
}

Redis 的特点

  • 高效的 内存缓存,适合处理高并发场景。
  • 通过 过期时间LRU 策略 等方式管理缓存。
  • Redis 可以设置 过期时间,比如:
redisTemplate.opsForValue().set("key", "value", 60, TimeUnit.SECONDS); // 缓存 60 秒后失效

三、缓存策略

1. 缓存穿透

缓存穿透是指查询一个在缓存和数据库中都不存在的数据,导致每次请求都要查询数据库。为了解决这个问题,可以使用 布隆过滤器(Bloom Filter),它能高效判断某个数据是否存在。

布隆过滤器示例:
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;public class BloomFilterExample {private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), 10000);public static void main(String[] args) {bloomFilter.put(12345);if (bloomFilter.mightContain(12345)) {System.out.println("数据可能存在");} else {System.out.println("数据不存在");}}
}
缓存策略说明解决方案
缓存穿透查询数据库中不存在的数据,缓存也不存,导致每次都要查询数据库。使用布隆过滤器,避免频繁查询无效数据。
缓存雪崩大量缓存同时失效,导致大量请求打到数据库,造成压力。随机化缓存过期时间,缓存预热。
缓存击穿高并发场景下,缓存的热点数据突然失效,大量请求直接查询数据库。使用互斥锁或延迟双删策略,防止缓存击穿。

2. 缓存雪崩

缓存雪崩是指在某个时间点大量缓存同时过期,导致大量请求打到数据库上,进而引发系统崩溃。解决缓存雪崩的方法包括:

  • 缓存过期时间随机化:在设定过期时间时加上一个随机值,避免大量缓存同时失效。
  • 缓存预热:在系统启动时,提前加载一部分热点数据到缓存中,避免缓存集中失效。
// 设置随机过期时间
long expireTime = 60 + new Random().nextInt(30); // 60秒 + 0-30秒的随机时间
redisTemplate.opsForValue().set("key", "value", expireTime, TimeUnit.SECONDS);

3. 缓存击穿

缓存击穿是指缓存中某些热点数据由于过期或未命中,导致大量并发请求直接打到数据库上。解决缓存击穿的常见方法是使用 互斥锁延迟双删策略

互斥锁示例:
public Object getWithLock(String key) {String value = redisTemplate.opsForValue().get(key);if (value == null) {// 加锁synchronized (this) {value = redisTemplate.opsForValue().get(key);if (value == null) {// 从数据库查询并回填缓存value = dbQuery(key);redisTemplate.opsForValue().set(key, value, 60, TimeUnit.SECONDS);}}}return value;
}

四、缓存失效策略

缓存失效是缓存系统中的一项重要设计。当缓存中的数据不再有效时,我们需要确保缓存失效能及时触发,避免系统读取到过期或无效的数据。常见的缓存失效策略有以下几种:

1. 基于时间的失效策略

最常见的缓存失效策略是基于时间的失效策略,即在缓存中设置 TTL(Time to Live),数据存活到达指定时间后自动失效。

代码示例

redisTemplate.opsForValue().set("key", "value", 60, TimeUnit.SECONDS); // 缓存 60 秒

2. 基于访问频率的失效策略

一些缓存系统提供了基于 LRU(Least Recently Used)LFU(Least Frequently Used) 的失效策略,自动删除最近未被使用或使用次数最少的数据。

Ehcache 的配置支持 LRU 失效策略:

<cache name="userCache" maxEntriesLocalHeap="1000" memoryStoreEvictionPolicy="LRU">
</cache>

3. 手动失效

某些场景下,当数据库中的数据发生变化时,我们需要手动删除缓存,保证缓存中的数据与数据库一致。

redisTemplate.delete("key"); // 手动删除缓存

手动失效通常与 发布订阅机制 结合使用,例如使用 Redis 的 Pub/Sub 功能,当某个节点更新数据时,通知其他节点删除或更新缓存。


五、总结

缓存 是提升系统性能的有效手段,但缓存的设计必须考虑到可能的 缓存穿透缓存雪崩缓存击穿 等问题。同时,合理设置缓存的 失效策略 是保证数据一致性的重要手段。

  1. Ehcache 适用于本地缓存,适合较小规模应用。
  2. Redis 作为分布式缓存,性能优越,支持多种缓存策略,适合高并发场景。
  3. 在实际应用中,缓存的设计应与业务需求紧密结合,确保在性能和数据一致性之间取得平衡。

合理的缓存设计能极大提高系统的可用性和响应速度,但我们也必须时刻警惕缓存带来的潜在问题,确保系统稳定高效地运行。

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

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

相关文章

使用库函数点亮一个LED灯

软件设计 STM32Gpio的介绍 如果想让LED0点亮&#xff0c;那么R12就要是高电平&#xff0c;LED0就要是低电平&#xff0c;也就是PF9就是低电平 F407系统主频要工作在168MHZ F103的话是工作在72mhz F429的话就180MHZ 接着我们就要使能Gpio的时钟&#xff0c;使能之后对GPIO相关…

YOLOV8输出预测框的坐标信息

结果&#xff1a;&#xff08;前提是对应类别的yolov8模型已经训练好&#xff09; 具体实现&#xff1a; 在ultralytics\utils\plotting.py里面 CtrlF搜索box_label 再次照片的最后一行输入&#xff1a; # 左上角cv2.putText(self.im, f"({p1[0]}, {p1[1]})", (p1…

19.初始C语言指针

初始C语言指针 1.指针的认识2.指针变量的引入3.指针变量的类型4.指针的应用场景15.指针的应用场景26.作业 1.指针的认识 指针 地址 //int a 10; //类型 变量名 内存地址 值 1.变量名直接访问2.通过地址访问&&#xff1a;取地址运算符* &#xff1a;将地址内的值读取…

Nacos未授权下载配置信息

0x01 漏洞描述&#xff1a; Nacos是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos存在未授权文件下载&#xff0c;攻击者在不登录情况下可未授权下载系统配置文件。 攻击者利用该漏洞可未授权获取到系统配置文件&#xff0c;如数据库和Redis连接地址…

【Delphi】创建应用程序和 LiveBindings示例(FMX)

一、创建一个FMX程序 界面上放置上如下3个控件&#xff1a;TProgressBar1, TArcDial1,TTrackBar1。 二、打开LiveBindings Designer 设计器 三、在 LiveBindings Designer 中&#xff0c;您的绑定图只包含对象&#xff0c;您可以将它们连接起来。 四、在设计器中&#xff0c;在…

openFrameworks_如何使用ofxXmlSettings和ofxGui来创建识别界面

效果图&#xff1a; 代码及详解 1.添加两个插件的头文件: #include "ofxGui.h" #include "ofxXmlSettings/src/ofxXmlSettings.h" 2.添加GUI部分&#xff0c;然后在.h声明右边的openframeworks的UI部分&#xff0c;包括面板ofxPanel&#xff0c;按钮ofx…

Tomcat 漏洞复现

1、CVE-2017-12615 1、环境开启 2、首页抓包&#xff0c;修改为 PUT 方式提交 Tomcat允许适用put方法上传任意文件类型&#xff0c;但不允许isp后缀文件上传&#xff0c;因此需要配合 windows的解析漏洞 3、访问上传的jsp文件 4、使用工具进行连接 2、后台弱⼝令部署war包 1…

简单了解一下SurfaceView

0 背景 最近好几次面试被问到SurfaceView的特点了&#xff0c;都没回答出来。 SurfaceView和TextureView也是Compose这样的声明式ui唯二实现不了控件&#xff1b;因为他们就不是View&#xff0c;而是Android提供的和Surface相关的显示系统 。 特此简单了解一下。 1 应用场景…

【Godot4.3】点数据简易表示法和Point2D

概述 在构造多点路径时我们会用到PackedVector2Array&#xff0c;并使用Vector2()来构造点。在手动创建多点数据时&#xff0c;这种写法其实很难看&#xff0c;有大量重复的Vector2()&#xff0c;比如下面这样&#xff1a; var points [Vector2(100,100),Vector2(200,200),V…

[Python]二、Python基础数据科学库(1)

F:\BaiduNetdiskDownload\2023人工智能开发学习路线图\2、机器学习核心技术\1、零基础快速入门机器学习 1.机器学习概述 1.1 人工智能概述 1.1.1 人工智能与机器学习、深度学习 1956年-达特茅斯会议-人工智能的起点 人工智能和机器学习、深度学习的关系: 1. 机器学习…

软考(9.22)

1 在浏览器的地址栏中输入xxxyftp.abc.can.cn&#xff0c;在该URL中( )是要访问的主机名。 A.xxxyftp B.abc C.can D.cn 协议://主机名.域名.域名后缀或IP地址(:端口号)/目录/文件名。 本题xxxyftp是主机名&#xff0c;选择A选项。 2 假设磁盘块与缓冲区大小相同&#xff0c;…

Django基础-创建新项目,各文件作用

学习Django的前置知识&#xff1a; python基本语法&#xff1a;需要掌握Python中的变量、循环、条件判断、函数等基本概念。面向对象编程&#xff08;OOP&#xff09;&#xff1a;Django的核心架构基于面向对象编程&#xff0c;许多功能&#xff08;如模型和视图&#xff09;依…

【无人机设计与控制】 基于matlab的蚁群算法优化无人机uav巡检

摘要 本文使用蚁群算法&#xff08;ACO&#xff09;优化无人机&#xff08;UAV&#xff09;巡检路径。无人机巡检任务要求高效覆盖特定区域&#xff0c;以最小化能源消耗和时间。本研究提出的算法通过仿生蚁群算法优化巡检路径&#xff0c;在全局搜索和局部搜索中平衡探索与开…

文档布局内容检测系统源码分享

文档布局内容检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer…

银河麒麟高级服务器操作系统V10外接硬盘挂载指南

银河麒麟高级服务器操作系统V10外接硬盘挂载指南 1、临时挂载外接硬盘2、永久挂载外接硬盘3、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在使用银河麒麟高级服务器操作系统V10时&#xff0c;您可能希望将外接硬盘&#xff08;如sd…

django应用JWT(JSON Web Token)实战

文章目录 一、什么是JWT二、为什么使用JWT三、在django项目中如何应用JWT1、安装djangorestframework-simplejwt库&#xff1a;2、在settings.py中配置JWT认证&#xff1a;3、在urls.py中配置JWT的获取和刷新路由&#xff1a; 四、JWT如何使用1、调用生成JWT的接口获取JWT2、客…

C/C++内存管理 ——

目录 五、C/C内存管理 1、C/C内存分布 2、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 3、C内存管理方式 1.new/delete操作内置类型 2.new和delete操作自定义类型 4、operator new与operator delete函数 5、new和delete的实现原理 1.内置类…

十六 未来信息综合技术(考点篇)试题

SaaS&#xff1a;软件即服务&#xff0c;PaaS&#xff1a;平台即服务&#xff0c;LaaS&#xff1a;基础设施即服务。 SaaS&#xff1a;偏向于提供各种软件接口来提供相关的服务&#xff1b;PaaS&#xff1a;偏向于吧一些基础的功能整合成一个平台&#xff0c;把整个平台或部分…

【人工智能】Linux系统Mamba安装流程

在编译安装 mamba 之前&#xff0c;你需要确保已安装正常的PyTorch环境。 # 安装必要的系统依赖 sudo apt update sudo apt install build-essential # 安装mamba依赖 pip install packaging wheel # 克隆仓库 git clone https://github.com/Dao-AILab/causal-conv1d.git git …

【python】修改字典的内容

person {"name": "John", "age": 30, "city": "New York"} print("最开始的信息&#xff1a;",person)def process_person_info(person):# 检查对象中是否包含所有必要的键if name in person and age in person …