【Ehcache】基础知识学习

  • 一、Ehcache概述

    • 1.1 简介
    • 1.2 Ehcache的主要特性
  • 二、Ehcache使用介绍
    • 2.1 Ehcache缓存过期策略
    • 2.2 如何解决缓存与db不同步的问题。
  • 三、Ehcache 基本项目演示
    • 3.1 Maven环境依赖
    • 3.2 YML配置文件信息
    • 3.3 App启动方式
    • 3.4 项目使用
    • 3.5 EhCache配置
    • 3.6 清除缓存
  • 四、Ehcache集群模式
    • 4.1 项目配置
    • 4.2 项目测试
    • 4.3 常用集群模式
      • RMi集群模式
    • 4.4 Ehcache的使用场景
    • 4.5 Redis和Ehcache缓存的区别
    • 4.6 实际工作中使用Ehcache

一、Ehcache概述

1.1 简介

Ehcache是纯java的开源缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。它主要面向通用缓存、Java EE和轻量级容器,具有内存和磁盘存储、缓存加载器、缓存扩展、缓存异常处理程序。
Ehcache最初由Greg Luck于2003年开始开发。2009年,该项目被Terracotta购买。软件仍然开源,但一些新的主要功能(例如,快速可重启性之间的一致性的)只能在商业产品中使用。
Ehcache 被广泛用于在Hibernate、Spring、Cocoon等其他开源系统。

1.2 Ehcache的主要特性

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

二、Ehcache使用介绍

  Ehcache是用来管理缓存的一个工具,其缓存的数据可以是存放在内存里面的,也可以是存放在硬盘上的。其核心是CacheManager,一切Ehcache的应用都是CacheManager开始的。它是用来管理Cache(缓存)的,一个应用可以有多个CacheManager,而一个CacheManager下又可以有多个Cache。Cache内部保存的是一个个的Element,而一个Element中保存的是一个key和value的配对,相当于Map里面的一个Entry。

?

2.1 Ehcache缓存过期策略

  当缓存需要被清理时(比如空间占用已经接近临界值了),需要使用某种淘汰算法来决定清理掉哪些数据。常用的淘汰算法有下面几种:

  1. FIFO:First In First Out,先进先出。判断被存储的时间,离目前最远的数据优先被淘汰。
  2. LRU:Least Recently Used,最近最少使用。判断最近被使用的时间,目前最远的数据优先被淘汰。
  3. LFU:Least Frequently Used,最不经常使用。在一段时间内,数据被使用次数最少的,优先被淘汰。

2.2 如何解决缓存与db不同步的问题。

项目中什么场景下会发生缓存与db不同步的问题
在生产环境下,是不可能随意直接改变数据库值。
update (修改)或者del (删除)

  1. 直接重启服务器
  2. 主动通知

update语句后面加上主动通知。
先修改,修改成功之后,在主动清理缓存,这是在同一个事务中。
改完了再清缓存啊万一修改失败呢?
定时JOB健康检查

三、Ehcache 基本项目演示

SpringBoot2.0整合Ehcache框架

3.1 Maven环境依赖

<!--开启 cache 缓存 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- ehcache缓存 -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
</dependency>

3.2 YML配置文件信息

###端口号配置
server:
  port: 8081
###数据库配置
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
    test-while-idle: true
    test-on-borrow: true
    validation-query: SELECT 1 FROM DUAL
    time-between-eviction-runs-millis: 300000
    min-evictable-idle-time-millis: 1800000
  # 缓存配置读取
  cache:
    type: ehcache
    ehcache:
      config: classpath:app1_ehcache.xml

3.3 App启动方式

@MapperScan(basePackages = { "com.itmayiedu.mapper" })
@EnableCaching
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}
// @EnableCaching 开启ehcache缓存模式

3.4 项目使用

@CacheConfig(cacheNames = "userCache")
public interface UserMapper {
    @Select("SELECT ID ,NAME,AGE FROM member where id=#{id}")
    @Cacheable
    List<Users> getUser(@Param("id") Long id);
}
//@Cacheable  加了该注解的方法表示可以缓存
//@CacheConfig 表示创建缓存配置,Key为userCache

3.5 EhCache配置

app1_ehcache.xml

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

    <diskStore path="java.io.tmpdir/ehcache-rmi-4000" />

    <!-- 默认缓存 -->
    <defaultCache maxElementsInMemory="1000" eternal="true"
        timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
        diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
        diskPersistent="true" diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
    </defaultCache>

    <!-- demo缓存 -->
    <cache name="userCache" maxElementsInMemory="1000" eternal="false"
        timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
        diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000000"
        diskPersistent="false" diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
        <cacheEventListenerFactory
            class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" />
        <!-- 用于在初始化缓存,以及自动设置 -->
        <bootstrapCacheLoaderFactory
            class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" />
    </cache>
</ehcache>

参数相关配置说明:

  1. diskStore标签:指定数据存储位置,可指定磁盘中的文件夹位置( The diskStore element is optional. It must be configured if you have overflowToDisk or diskPersistent enabled for any cache. If it is not configured, a warning will be issues and java.io.tmpdir will be used.)
  2. defaultCache标签:默认的管理策略,Ehcache 使用Map集合实现的 element 其实就是 key 和value
  • 以下属性是必须的:

    • 1、name: Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里)。
    • 2、maxElementsInMemory:在内存中缓存的element的最大数目。
    • 3、maxElementsOnDisk:在磁盘上缓存的element的最大数目,默认值为0,表示不限制。
    • 4、eternal:设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断。
    • 5、overflowToDisk: 如果内存中数据超过内存限制,是否要缓存到磁盘上。
  • 以下属性是可选的:
    • 1、timeToIdleSeconds: 对象空闲时间,指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问。
    • 2、timeToLiveSeconds: 对象存活时间,指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问。
    • 3、diskPersistent: 是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false。
    • 4、diskExpiryThreadIntervalSeconds: 对象检测线程运行时间间隔。标识对象状态的线程多长时间运行一次。
    • 5、diskSpoolBufferSizeMB: DiskStore使用的磁盘大小,默认值30MB。每个cache使用各自的DiskStore。
    • 6、memoryStoreEvictionPolicy: 如果内存中数据超过内存限制,向磁盘缓存时的策略。默认值LRU,可选FIFO、LFU。

3.6 清除缓存

@Autowired
private CacheManager cacheManager;
@RequestMapping("/remoKey")
public void remoKey() {
  cacheManager.getCache("userCache").clear();
}

  

四、Ehcache集群模式

  由于 EhCache 是进程中的缓存系统,一旦将应用部署在集群环境中,每一个节点维护各自的缓存数据,当某个节点对缓存数据进行更新,这些更新的数据无法在其它节点中共享,这不仅会降低节点运行的效率,而且会导致数据不同步的情况发生。例如某个网站采用 A、B 两个节点作为集群部署,当 A 节点的缓存更新后,而 B 节点缓存尚未更新就可能出现用户在浏览页面的时候,一会是更新后的数据,一会是尚未更新的数据,尽管我们也可以通过 Session Sticky 技术来将用户锁定在某个节点上,但对于一些交互性比较强或者是非 Web 方式的系统来说,Session Sticky 显然不太适合。

4.1 项目配置

  将上面的app1_ehcache.xml复制一份,命名为app2_ehcache.xml
这两个XML文件分别添加如下配置:

app1_ehcache.xml:


<!-- 多台机器配置 rmiUrls=//192.168.8.32:400002/demoCache|//192.168.5.231:400003/demoCache -->
<cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=manual,rmiUrls=//127.0.0.1:5000/userCache">
</cacheManagerPeerProviderFactory>
<!-- 配置 rmi 集群模式 -->
<cacheManagerPeerListenerFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
    properties="hostName=127.0.0.1,port=4000,socketTimeoutMillis=120000" />

<!-- 多播方式配置 搜索某个网段上的缓存 timeToLive 0是限制在同一个服务器 1是限制在同一个子网 32是限制在同一个网站 64是限制在同一个region
    128是限制在同一个大洲 255是不限制 <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=automatic, multicastGroupAddress=224.1.1.1, multicastGroupPort=40000,
    timeToLive=32" /> -->

app2_ehcache.xml:

<!-- 多台机器配置 -->
<cacheManagerPeerProviderFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=manual,rmiUrls=//127.0.0.1:4000/userCache">
</cacheManagerPeerProviderFactory>

<cacheManagerPeerListenerFactory
    class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
    properties="hostName=127.0.0.1,port=5000,socketTimeoutMillis=120000" />

<!-- 多播方式配置 搜索某个网段上的缓存 timeToLive 0是限制在同一个服务器 1是限制在同一个子网 32是限制在同一个网站 64是限制在同一个region
    128是限制在同一个大洲 255是不限制 <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=automatic, multicastGroupAddress=224.1.1.1, multicastGroupPort=40000,
    timeToLive=32" /> -->

4.2 项目测试

修改yml文件分别以8080端口+app1_ehcache.xml 和 8081端口+app2_ehcache.xml启动SpringBoot项目:

  • 1.数据库中的数据:

?

  • 2.访问 http://127.0.0.1:8080/getUser?id=2 可以正常查到数据:

?

  • 3.访问 http://127.0.0.1:8081/getUser?id=2可以正常查到数据

?

  • 4.直接手动修改数据库中的数据:

?

  • 5.在此访问上述接口发现,查出来的数据name还是“明人”,原因是因为缓存的缘故
  • 6.调用清除缓存的接口 http://127.0.0.1:8080/remoKey ,注意此时清除的是8080端口的缓存,
  • 7.调用此接口 http://127.0.0.1:8080/getUser?id=2,可以重新查询到数据库中的值“小明”,但是可以发现8081端口下的缓存也被清除了,这就是配置了EhCache集群的缘故。

?

?

4.3 常用集群模式

  EhCache从1.7版本开始,支持五种集群方案,分别是:Terracotta、RMI、JMS、JGroups、EhCache Server

RMi集群模式

你如何知道集群环境中的其他缓存?
分布式传送的消息是什么形式?
什么情况需要进行复制?增加(Puts),更新(Updates)或是失效(Expiries)?
采用什么方式进行复制?同步还是异步方式?

  • 1、正确的元素类型:只有可序列化的元素可以进行复制。一些操作,比如移除,只需要元素的键值而不用整个元素;在这样的操作中即使元素不是可序列化的但键值是可序列化的也可以被复制。
  • 2、成员发现(Peer Discovery):Ehcache进行集群的时候有一个cache组的概念。每个cache都是其他cache的一个peer,没有主cache的存在。成员发现(Peer Discovery)正是用来解决 “你如何知道集群环境中的其他缓存?” 这个问题的。Ehcache提供了两种机制用来进行成员发现,即:自动成员发现和手动成员发现。要使用一个内置的成员发现机制要在ehcache的配置文件中指定cacheManagerPeerProviderFactory元素的class属性为 net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory。

4.4 Ehcache的使用场景

  • 使用纯java的ehcache作为本地缓存
  • Reids 作为远程分布式缓存
  • 解决redis缓存压力过大,提高缓存速度,以及缓存性能。

4.5 Redis和Ehcache缓存的区别

  • 如果是单个应用或者对缓存访问要求很高的应用,用ehcache。
  • 如果是大型系统,存在缓存共享、分布式部署、缓存内容很大的,建议用redis。

4.6 实际工作中使用Ehcache

  • 我们在项目中使用集中式缓存(Redis或者式Memcached等),通常都是检查缓存中是否存在
  • 期望值的数据,如果存在直接返回,如果不存在就查询数据库让后在将数据库缓存,
  • 这个时候如果缓存系统因为某写原因宕机,造成服务无法访问,那么大的量请求直接穿透到数据库,最数据库压力非常大。
  • 这时候我们让ehcache作为二级缓存,当redis服务器宕机后,可以查询ehcache缓存。
  • 这样能够有效的扛住服务器请求压力。

原文地址:https://www.cnblogs.com/haoworld/p/ehcache-ji-chu-zhi-shi-xue-xi.html

时间: 2024-10-11 06:11:34

【Ehcache】基础知识学习的相关文章

计算机基础知识学习

第一周学习 一.知识方面,总得来说,就是学习计算机基础知识. 1.从计算机的发展,应用,组成,网络等方面了解: 2.对计算机操作系统的学习:常用的操作系统,操作系统的功能.分类: 3.办公软件的学习:Word\Excel\ppt,像Word中编号格式.自动生成目录,Excel中条件格式的应用,图表插入,以及各种基础函数的使用: =SUM(Eoo*$E$3,Foo*$F$3,Goo*$G$3)  表示:用E\F\G列的各数与E3\F3\G3相乘后求和,count(if)\a 计数函数, =COUN

ARM基础知识学习笔记

/*****************数电知识*******************/ PN结(Positive-Negative) 三极管:BJT(双极结型三极管Bipolar Junction Transistor)               FET(场效应管Field Effect Transistor)          (单极结型) 1.MOSFET (金属氧化物半导体Metal Oxide Semiconductor FET)               2.JFET(结型Junct

C++基础知识学习笔记

基本语法 C面向过程思想:程序=(数据结构)+(算法) 数据结构与算法分离,以算法(函数)为主. C++面向对象思想:程序=(数据结构+算法) 数据结构(属性)与算法(操作)绑成一个类,定义一个个对象对象=(数据结构+算法)  ,程序=(对象+对象+对象+--) 面向对象程序设计的程序员有两类:1.面向对象应用程序设计2.类库的设计 头文件:类的声明            ---类的外部接口       (成员函数在类声明中实现时,一般很简短,默认为内联函数)源文件:类的成员函数定义     -

linux基础知识学习-linux架构

硬盘分区: 第一扇区(512bytes): MSR:master boot record (446bytes)主引导分区 partion table:(64bytes)分区表,四个.可以是主分区(primary)或者扩展分区(Extended), 每个表指向磁盘某段区间.最多只有一个扩展分区,扩展分区里面可以扩展多个逻辑分区.其余扇区(柱面(cylinder)):实际存储的地方 linux 中(\etc/fstab):IDE  总线形式不同 (a~d)/dev/hda SATA,SCSI,USB

Bash编程基础知识学习第一节

Bash编程基础知识学习 一.bash的由来 1 .什么是Bash 什么是Shell Bash 是GNU Bourne-Again SHell,是目前大多数Linux发行版采用的Shell. Shell 是*nix提供给用户使用的界面.一个操作系统的底层是独立运行的, 用户界面和底层分开,可以最大限度的保证系统稳定.Shell就是一个特殊的程序,负责接受用户的命令,并把系统的响应返回给用户. Bash Shell 一般不需要自己安装,在安装发行版的同时都会安装好. Shell的存在是和登陆相关的

(转)Linux基础知识学习

Linux基础知识学习 原文:http://blog.csdn.net/ye_wei_yang/article/details/52777499 一.Linux的磁盘分区及目录 Linux的配置是通过修改配置文件来完成. 1.1.Linux磁盘分区 Linux可以将磁盘分为多个分区,每个分区可以被当做一个独立的磁盘使用,磁盘类型:主分区.扩展分区.逻辑分区. 主分区标记为活动,用于操作系统的引导,一块磁盘最多划分4个主分区,主分区存放操作系统的文件或用户数据. 扩展分区:主分区小于4个时才可以划

PHP基础知识学习总结

从今天开始过一遍PHP的基础知识   加油  地址:http://www.runoob.com/php/php-operators.html   该看:PHP运算符 2017年5月23日23:38:30 笔记: PHP基础知识2017年5月23日23:38:411.PHP 是一种创建动态交互性站点的强有力的服务器端脚本语言.2.PHP 是服务器端脚本语言.3.PHP(全称:PHP:Hypertext Preprocessor,即"PHP:超文本预处理器")是一种通用开源脚本语言.PHP

〖前端开发〗HTML/CSS基础知识学习笔记

经过一天的学习,把慕课网的HTML/CSS基础知识学完了,笔记整理: 1. 文件结构: HTML文件的固定结构: <html> <head>...</head> <body>...</body> </html> html是根标签 head定义文档头部,包含: title, script, style, link, meta body是网页主要内容,包含:h1,h2-h6, p, a, img 2. 认识head标签: <head

web前端基础知识学习网站推介

内容:一.基础知识及学习资料1. HTML入门学习:http://www.w3school.com.cn/html/index.aspHTML5 入门学习:http://www.w3school.com.cn/html5/index.asp 2. CSS入门学习:http://www.w3school.com.cn/css/index.aspCSS3入门学习:http://www.w3schools.com/css3/default.asphttp://css3-tutorial.com/ 3.

ZooKeeper_基础知识学习

ZooKeeper是Hadoop的开源子项目(Google Chubby的开源实现),它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护.命名服务.分布式同步.组服务等. Zookeeper的Fast Fail 和 Leader选举特性大大增强了分布式集群的稳定和健壮性,并且解决了Master/Slave模式的单点故障重大隐患,这是越来越多的分布式产品如HBase.Storm(流计算).S4(流计算)等强依赖Zookeeper的原因. Zookeeper在分布式集群(Hadoop