Ehcache Java 缓存框架

2024-05-31 23:28
文章标签 java 框架 缓存 ehcache

本文主要是介绍Ehcache Java 缓存框架,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

详解

下图是 Ehcache 在应用程序中的位置:

Ecache 是一个广泛使用的 Java 缓存框架,能够有效提升应用性能,并减少与后端数据库的交互次数。它采用了一系列高级缓存策略,包括内存缓存、磁盘缓存、分布式缓存等,并提供了丰富的 API 和工具类,可以方便地完成缓存的读写和管理。快速:Ecache 采用了一系列高效的缓存策略,能够实现快速的数据访问和读写,从而提高应用程序的性能。可扩展:Ecache 支持分布式缓存,可以方便地扩展到多台服务

一、Ehcache 简

Ehcache 是一个广泛使用的 Java 缓存框架,能够有效提升应用性能,并减少与后端数据库的交互次数。它采用了一系列高级缓存策略,包括内存缓存、磁盘缓存、分布式缓存等,并提供了丰富的 API 和工具类,可以方便地完成缓存的读写和管理。

Ehcache 主要有以下特点:

  • 快速:Ehcache 采用了一系列高效的缓存策略,能够实现快速的数据访问和读写,从而提高应用程序的性能。
  • 可扩展:Ehcache 支持分布式缓存,可以方便地扩展到多台服务器上,从而提高系统的容错性和吞吐量。
  • 可靠性高:Ehcache 内置了多种缓存策略,支持数据持久化和恢复,同时还提供了完善的故障检测和纠正机制,从而保证了缓存数据的可靠性和稳定性。
  • 易于使用:Ehcache 提供了丰富的 API 和工具类,可以方便地完成缓存的读写和管理。同时,它还与多种框架和技术集成,如 Spring、Hibernate、MyBatis 等,使得用户可以更加便捷地使用 Ecache。

二、工作原理

1. 缓存写入

当应用程序向 Ehcache 中写入数据时,Ehcache 会首先检查该数据是否已经存在于缓存中。如果数据已经存在于缓存中,则更新该数据;否则,将该数据写入缓存。以下是 Ehcache 缓存写入的详细流程。

  1. 当应用程序请求写入一个数据项到 Ehcache 中时,这个数据项被传递给Ehcache API。

  2. Ehcache首先根据该数据项的键值对定位其对应的Cache对象。

  3. Ehcache根据配置中的缓存策略,比如是否应该在缓存中创建一个新的元素,以及新元素是否会淘汰老的元素。

  4. 如果需要创建一个新缓存元素,则Ehcache创建一个新的元素并将其添加到Cache对象中。

  5. 如果缓存中已经存在该元素,Ehcache会根据缓存策略对该元素进行更新或替换。

  6. Ehcache将更新后的Cache对象返回给应用程序。

2. 缓存查找

当应用程序需要查询缓存中的数据时,Ehcache 首先会检查该数据是否存在于缓存中。如果数据存在于缓存中,则直接返回缓存数据;否则,从数据库或其他资源获取数据,并将其存入缓存中。以下是 Ehcache 缓存查找的详细流程。

  1. 当应用程序请求从 Ehcache 中读取一个数据项时,这个请求被传递给Ehcache API。

  2. Ehcache首先根据该数据项的键值对定位其对应的Cache对象。

  3. Ehcache检查该数据项是否已经存在于缓存中。

  4. 如果数据项存在于缓存中,Ehcache可以直接将其返回给应用程序。

  5. 如果数据项不存在于缓存中,Ehcache就需要从数据库或其他数据源(如文件、网络等)中获取数据。

  6. 获取到数据后,Ehcache会将其添加到缓存中并返回给应用程序。

3. 缓存过期和驱逐

Ehcache 提供了多种缓存失效策略,例如基于时间的缓存失效、基于访问的缓存失效、基于大小的缓存失效等。当缓存数据过期或缓存空间不足时,Ehcache 会选择一部分缓存元素进行驱逐以腾出更多的内存空间。以下是 Ehcache 缓存过期和驱逐的详细流程。

  1. Ehcache会周期性地扫描缓存中的元素来标记那些已经过期的元素。

  2. Ehcache根据缓存策略(如基于时间、基于访问、基于大小等)判断哪些缓存元素应该被驱逐。

  3. 驱逐过程通常是异步执行的,Ehcache会在后台线程上执行这个操作。

4. 缓存持久化

Ehcache 还提供了缓存持久化功能,它可以将缓存中的数据持久化到磁盘或者其他数据源。在应用程序重启或者缓存失效后,Ehcache 可以从持久化存储中恢复数据,从而保证数据的完整性和可靠性。以下是 Ehcache 缓存持久化的详细流程。

  1. Ehcache使用磁盘存储或数据库等持久化技术来存储缓存数据。

  2. 当缓存中的数据更新时,Ehcache会自动将此数据持久化到持久化存储中。

  3. 在应用程序重启或者缓存失效后,Ehcache会从持久化存储中读取缓存数据并重新加载到内存中。

三、Ehcache 的基本使用

Spring Boot 中集成 Ehcache 缓存代码示例。

1. 添加 Ehcache 依赖

首先需要在项目的 pom.xml 文件中添加 Ehcache 缓存依赖,如下所示:

<dependency><groupId>org.ehcache</groupId><artifactId>ehcache</artifactId><version>3.9.3</version>
</dependency>
2. 配置 Ehcache

在 application.yml 或 application.properties 配置文件中添加 Ehcache 的配置信息,例如:

spring:ehcache:config: classpath:ehcache.xml

在上述配置中,我们指定了 Ehcache 的配置文件为 classpath:ehcache.xml,这样 Spring Boot 在启动时会自动加载该配置文件。

接下来,需要在 src/main/resources 目录下添加 ehcache.xml 配置文件,并编写相应的 Ehcache 配置信息。例如,下面是一个简单的 Ehcache 配置文件:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.ehcache.org/v3"xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd"><cache alias="myCache"><key-type>java.lang.String</key-type><value-type>java.lang.String</value-type><expiry><ttu value="10m"/></expiry><heap>100</heap></cache></config>

在上述配置中,我们定义了一个名为 myCache 的缓存,配置了键值类型、过期时间、最大存储数量等参数。

3. 使用 Ehcache

在完成 Ehcache 的配置后,就可以在 Spring Boot 中使用 Ehcache 缓存了。Spring Boot 提供了 @Cacheable@CachePut@CacheEvict 等注解来简化缓存操作,同时也支持基于缓存管理器的编程方式。

3.1 基于注解的缓存

首先介绍一下基于注解的缓存。Spring Boot 中,可以通过 @Cacheable@CachePut 和 @CacheEvict 注解来实现对缓存的读写和删除操作。

3.1.1 @Cacheable 注解

@Cacheable 注解用于指定方法的返回值可被缓存,同时也可以指定缓存的 key 和 cacheNames,例如:

@Service
public class UserService {@Cacheable(cacheNames = "myCache", key = "#userId")public User getUserById(String userId) {System.out.println("get user by id: " + userId);return new User(userId, "张三");}}

在上述代码中,我们使用 @Cacheable 注解将 getUserById() 方法返回值进行缓存,并指定了缓存的 key 为 userId,缓存名称为 myCache

3.1.2 @CachePut 注解

@CachePut 注解用于更新缓存中的数据,例如:

@Service
public class UserService {@CachePut(cacheNames = "myCache", key = "#user.id")public User updateUser(User user) {System.out.println("update user: " + user);return user;}}

在上述代码中,我们使用 @CachePut 注解更新了缓存中键为 user.id 的缓存数据。

3.1.3 @CacheEvict 注解

@CacheEvict 注解用于清除缓存中的数据,例如:

@Service
public class UserService {@CacheEvict(cacheNames = "myCache", key = "#userId")public void deleteUserById(String userId) {System.out.println("delete user by id: " + userId);}}

在上述代码中,我们使用 @CacheEvict 注解清除了缓存中键为 userId 的缓存数据。

3.2 基于缓存管理器的编程方式

除了注解方式外,还可以基于缓存管理器的编程方式来实现对缓存的读写和删除操作。Spring Boot 中,可以使用 CacheManager 和 Cache 接口来实现缓存的管理和操作。

3.2.1 注入缓存管理器

使用基于缓存管理器的编程方式,首先需要注入使用的缓存管理器,例如:

@Service
public class UserService {@Autowiredprivate CacheManager cacheManager;}

在上述代码中,我们注入了 CacheManager 类型的 cacheManager 实例。

3.2.2 获取缓存实例

获取缓存实例的方式也很简单,可以通过缓存管理器的 getCache() 方法获取:

@Service
public class UserService {@Autowiredprivate CacheManager cacheManager;public User getUserById(String userId) {Cache cache = cacheManager.getCache("myCache");Element element = cache.get(userId);if (element != null) {System.out.println("get user by id from cache: " + userId);return (User) element.getObjectValue();}System.out.println("get user by id from db: " + userId);User user = new User(userId, "张三");cache.put(new Element(userId, user));return user;}}

在上述代码中,我们使用缓存管理器的 getCache() 方法获取名为 myCache 的缓存实例。然后,我们使用缓存实例的 get() 方法获取指定 key 对应的缓存元素,如果获取到了元素,则直接返回缓存数据;否则,从数据库中获取数据,并将其存入缓存中。

3.2.3 缓存操作

除了读取缓存数据外,我们还可以使用缓存实例的 put() 方法向缓存中添加数据,使用 remove() 方法删除缓存数据,例如:

@Service
public class UserService {@Autowiredprivate CacheManager cacheManager;public User updateUser(User user) {Cache cache = cacheManager.getCache("myCache");cache.put(new Element(user.getId(), user));return user;}public void deleteUserById(String userId) {Cache cache = cacheManager.getCache("myCache");cache.remove(userId);}}

在上述代码中,我们分别使用了缓存实例的 put() 和 remove() 方法对缓存数据进行了更新和清除操作。

四、 Ehcache 的高级用法

1. 缓存策略

Ehcache 提供了多种缓存策略,可以根据实际需求选择合适的策略。其中,最常用的包括:

  • LRU(Least Recently Used):移除最近最少使用的缓存项。
  • LFU(Least Frequently Used):移除最不经常使用的缓存项。
  • FIFO(First In, First Out):先进先出,即移除最早加入的缓存项。
  • TTL(Time To Live):根据缓存项的过期时间来判断是否要移除该项。
  • 随机替换:随机选择一项进行移除。

在 Ehcache 中,默认使用的是 LRU 策略。如果需要更改策略,可以在 ehcache.xml 配置文件中进行设置。

2. 内存缓存和磁盘缓存

Ehcache 支持将缓存数据同时存储在内存和磁盘上,并根据实际情况调整数据的存储位置。例如,可以将经常访问的缓存数据存储在内存中,而不常使用的数据则存储在磁盘上,从而达到提高缓存效率和降低成本的目的。

在 ehcache.xml 配置文件中,可以通过 <heap><offheap> 和 <disk> 标签来定义缓存存储的位置。例如,下面的配置将缓存数据存储在内存中,并限制最大存储数量为 100 个:

<cache alias="myCache"><key-type>java.lang.String</key-type><value-type>java.lang.String</value-type><heap>100</heap>
</cache>

如果需要将部分缓存数据存储在磁盘上,可以添加如下配置:

<cache alias="myCache"><key-type>java.lang.String</key-type><value-type>java.lang.String</value-type><heap>10</heap> <!-- 最多存储 10 个缓存项到堆中 --><offheap>1MB</offheap> <!-- 最多存储 1MB 缓存项到堆外内存中 --><diskPersistent>true</diskPersistent> <!-- 开启磁盘持久化,即使程序重启后,缓存仍然有效 --><diskSpoolBufferSizeMB>30</diskSpoolBufferSizeMB> <!-- 磁盘缓存区大小,缓存数据先以临时文件的形式写入磁盘缓存区,待达到一定阈值后再写入磁盘 --><diskExpiryThreadIntervalSeconds>120</diskExpiryThreadIntervalSeconds> <!-- 磁盘数据过期检测间隔时间,单位为秒 --><maxEntriesLocalDisk>1000</maxEntriesLocalDisk> <!-- 磁盘缓存最大存储数量 -->
</cache>
3. 分布式缓存

Ehcache 提供了分布式缓存的支持,并可以通过 RMI、JMS、Spring 等方式进行实现。在分布式环境下,每个缓存节点都可以通过网络访问远程节点上的缓存数据,从而实现数据共享和分布式缓存的目的。

在 ehcache.xml 配置文件中,可以添加 <cacheManagerPeerProviderFactory> 和 <cacheManagerPeerListenerFactory> 标签来定义缓存节点的配置信息。例如,下面的配置定义了一个名为 myCache 的缓存,采用了 RMI 方式实现分布式缓存:

<cache-manager-peer-provider-factory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"properties="peerDiscovery=automatic,multicastGroupAddress=230.0.0.1,multicastGroupPort=4446,timeToLive=32"/><cache-manager-peer-listener-factory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"properties="port=40001,socketTimeoutMillis=2000"/><cache alias="myCache"><key-type>java.lang.String</key-type><value-type>java.lang.String</value-type><diskPersistent>true</diskPersistent><diskSpoolBufferSizeMB>30</diskSpoolBufferSizeMB><maxEntriesLocalDisk>1000</maxEntriesLocalDisk><cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"properties="replicateAsynchronously=true,replicatePuts=true,replicateUpdates=true,replicateUpdatesViaCopy=false,replicateRemovals=true"/>
</cache>

在上述配置中,我们首先定义了一个 RMI 的缓存管理器提供者工厂 RMICacheManagerPeerProviderFactory 和一个 RMI 的缓存管理器监听器工厂 RMICacheManagerPeerListenerFactory,并分别指定了自动发现、组播地址、端口等相关参数。

接着,我们定义了名为 myCache 缓存添加了一个 cacheEventListenerFactory 属性,用于定义缓存事件的处理方式,即使用 RMICacheReplicatorFactory 实现缓存数据的复制和同步。

需要注意的是,分布式缓存的配置和使用与单机缓存有所不同,同时也需要考虑到网络通信等问题,因此更加复杂和耗费资源。在选择是否需要使用分布式缓存时,需要权衡其带来的性能、复杂性和成本等因素。

这篇关于Ehcache Java 缓存框架的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1019340

相关文章

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

SpringBoot整合OpenFeign的完整指南

《SpringBoot整合OpenFeign的完整指南》OpenFeign是由Netflix开发的一个声明式Web服务客户端,它使得编写HTTP客户端变得更加简单,本文为大家介绍了SpringBoot... 目录什么是OpenFeign环境准备创建 Spring Boot 项目添加依赖启用 OpenFeig

Java Spring 中 @PostConstruct 注解使用原理及常见场景

《JavaSpring中@PostConstruct注解使用原理及常见场景》在JavaSpring中,@PostConstruct注解是一个非常实用的功能,它允许开发者在Spring容器完全初... 目录一、@PostConstruct 注解概述二、@PostConstruct 注解的基本使用2.1 基本代

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

SpringBoot整合mybatisPlus实现批量插入并获取ID详解

《SpringBoot整合mybatisPlus实现批量插入并获取ID详解》这篇文章主要为大家详细介绍了SpringBoot如何整合mybatisPlus实现批量插入并获取ID,文中的示例代码讲解详细... 目录【1】saveBATch(一万条数据总耗时:2478ms)【2】集合方式foreach(一万条数

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖

SpringBoot中配置文件的加载顺序解读

《SpringBoot中配置文件的加载顺序解读》:本文主要介绍SpringBoot中配置文件的加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot配置文件的加载顺序1、命令⾏参数2、Java系统属性3、操作系统环境变量5、项目【外部】的ap

SpringBoot UserAgentUtils获取用户浏览器的用法

《SpringBootUserAgentUtils获取用户浏览器的用法》UserAgentUtils是于处理用户代理(User-Agent)字符串的工具类,一般用于解析和处理浏览器、操作系统以及设备... 目录介绍效果图依赖封装客户端工具封装IP工具实体类获取设备信息入库介绍UserAgentUtils

Spring 中的循环引用问题解决方法

《Spring中的循环引用问题解决方法》:本文主要介绍Spring中的循环引用问题解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录什么是循环引用?循环依赖三级缓存解决循环依赖二级缓存三级缓存本章来聊聊Spring 中的循环引用问题该如何解决。这里聊

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen