EhCache

EhCache一、简介Ehcache是一个用Java实现的使用简单,高速,实现线程安全的缓存管理类库,ehcache提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案。同时ehcache作为开放源代码项目,采用限制比较宽松的ApacheLicenseV2.0作为授权方式,被广泛地用于Hibernate,Spring,Cocoon等其他开源系统。Ehcache从Hibe…

一、简介

Ehcache是一个用Java实现的使用简单,高速,实现线程安全的缓存管理类库,ehcache提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案。同时ehcache作为开放源代码项目,采用限制比较宽松的Apache License V2.0作为授权方式,被广泛地用于Hibernate, Spring,Cocoon等其他开源系统。Ehcache 从 Hibernate 发展而来,逐渐涵盖了 Cahce 界的全部功能,是目前发展势头最好的一个项目。具有快速,简单,低消耗,依赖性小,扩展性强,支持对象或序列化缓存,支持缓存或元素的失效,提供 LRU、LFU 和 FIFO 缓存策略,支持内存缓存和磁盘缓存,分布式缓存机制等等特点。

二、主要特性

快速;
简单;
多种缓存策略;
缓存数据有两级:内存和磁盘,因此无需担心容量问题;
缓存数据会在虚拟机重启的过程中写入磁盘;
可以通过 RMI、可插入 API 等方式进行分布式缓存;
具有缓存和缓存管理器的侦听接口;
支持多缓存管理器实例,以及一个实例的多个缓存区域;
提供 Hibernate 的缓存实现;

三、Ehcache的架构设计图

EhCache

说明
CacheManager:是缓存管理器,可以通过单例或者多例的方式创建,也是Ehcache的入口类。
Cache:每个CacheManager可以管理多个Cache,每个Cache可以采用hash的方式管理多个Element。
Element:用于存放真正缓存内容的。

结构图如下所示:

EhCache

四、Ehcache的缓存数据淘汰策略

淘汰策略指的是当缓存满了的时候,Ehcache会根据指定的策略来清理缓存。Ehcache中缓存的最大Element数是由maxElementsInMemory来指定的。当缓存中的Element个数达到maxElementsInMemory指定的值时,Ehcache会根据具体的策略来清理缓存,默认的策略是LRU(最近最少使用)。

FIFO:先进先出
LFU:最少被使用,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
LRU:默认,最近最少使用,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

五、Ehcache的缓存数据过期策略

过期策略指的是数据过期的时候,Ehcache会根据指定的策略来清理缓存。Ehcache采用的是懒淘汰机制,每次往缓存放入数据的时候,都会存一个时间,在读取的时候要和设置的时间做TTL比较来判断是否过期。

六、Ehcache集群的基本概念,成员发现(Peer Discovery)

Ehcache集群概念中有一个cache组,每个cache都是另一个cache的peer,并不像Redis或者其他分布式组件一样有一个主的存在,Ehcache并没有主Cache,可是那如何知道集群中的其他缓存都有谁呢?这个就是成员发现。Ehcache提供了二种机制来实现成员发现功能,分别是手动发现和自动发现。

二、实践

  1、新建一个Maven项目,项目结构如图所示

EhCache

2、ehcache.xml(采用RMI自动成员发现的方式)

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">

	<!--缓存成员发现工厂,管理cacheManager对象 
	        当缓存改变时,ehcache会向230.0.0.1端口4446发RMI UDP组播包 
		mulicastGroupAddress 广播组地址 
		mulicastGroupPort 广播组端口 
		multicastPacketTimeToLive 
		0是限制在同一个服务器 
		1是限制在同一个子网
		32是限制在同一个网站 
		64是限制在同一个region 
		128是限制在同一个大洲 
		255是不限制 -->
	<cacheManagerPeerProviderFactory
		class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
		properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446,
        multicastPacketTimeToLive=32"/>

	<cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" />
            
    <!--
       diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
       user.home – 用户主目录
       user.dir  – 用户当前工作目录
       java.io.tmpdir – 默认临时文件路径
     -->
    <diskStore path="java.io.tmpdir"/>
    <!--
      defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
      name:缓存名称。
      maxElementsInMemory:缓存最大数目
      maxElementsOnDisk:硬盘最大缓存个数。
      eternal:对象是否永久有效,一但设置了,timeout将不起作用。
      overflowToDisk:是否保存到磁盘,当系统当机时
      timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
      timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
      diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
      diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
      diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
      memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
      clearOnFlush:内存数量最大时是否清除。
      memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
      FIFO,first in first out,这个是大家最熟的,先进先出。
      LFU,Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
      LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
      replicatePuts=true | false – 当一个新元素增加到缓存中的时候是否要复制到其他的peers. 默认是true。 
	  replicateUpdates=true | false – 当一个已经在缓存中存在的元素被覆盖时是否要进行复制。默认是true。 
	  replicateRemovals= true | false – 当元素移除的时候是否进行复制。默认是true。 
	  replicateAsynchronously=true | false – 复制方式是异步的(指定为true时)还是同步的(指定为false时)。默认是true。 
	  replicatePutsViaCopy=true | false – 当一个新增元素被拷贝到其他的cache中时是否进行复制指定为true时为复制,默认是true。
   -->
    <defaultCache
            eternal="false"
            maxElementsInMemory="10000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>
 
    <cache
            name="user"
            eternal="false"
            maxElementsInMemory="1000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="60"
            timeToLiveSeconds="60"
            memoryStoreEvictionPolicy="LRU" >
     <cacheEventListenerFactory  
            class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"  
            properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,replicateUpdatesViaCopy=false, replicateRemovals=true " />
        <bootstrapCacheLoaderFactory  
            class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
    </cache>
</ehcache>

3、Application

package com.yj;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class Application{
	public static void main(String[] args) throws Exception {
		SpringApplication.run(Application.class, args);
	}
}

4、application.properties

server.port=8080
spring.application.name=cache

spring.datasource.url = jdbc:mysql://192.168.225.128:3306/docker?useSSL=false
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver

mybatis.mapperLocations=classpath:mapper/*.xml

ehcache.cacheNames=user

spring.cache.jcache.config=classpath:ehcache.xml

5.pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.yj</groupId>
  <artifactId>EhCache</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>EhCache</name>
  <url>http://maven.apache.org</url>

 <properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.2.RELEASE</version>
		<relativePath />
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
		<dependency>
			<groupId>net.sf.ehcache</groupId>
			<artifactId>ehcache</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.11</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.3.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.8</version>
		</dependency>
	</dependencies>
</project>

二、测试

  • 测试单机非集群的情况,启动8080端口的应用

         ①新增用户A->②查询用户A->③修改用户A->④查询用户A->⑤删除用户A->⑥查询用户A

         步骤②不会查询数据库,步骤④查询了数据库,步骤⑥查询了数据库

  • 集群的情况,分别启动8080,8089端口的应用

         ①80/89端口新增用户->②80/89端口查询用户->③80/89端口修改用户->④80/89端口查询用户->⑤80/89端口删除用户->⑥80/89端口查询用户

         步骤②不会查询数据库,步骤④89/80查询了数据库,步骤⑥89/80查询了数据库,证明两个应用之间的缓存会进行同步,达到了预期的效果

 

今天的文章EhCache分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/6218.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注