Ehcache 学习入门
一、介绍
网上有很多关于Ehcache的介绍,这里就不在多说了,只需要知道Ehcache是一个缓存框架。缓存嘛,就是数据存取比硬盘快,但是容量小的存储区域。当我们需要频繁使用某些数据时,我们可以将这些数据放到缓存中,下次取数据的时候,直接从缓存中取,这样可以节省不少时间。如果我们自己手动进行缓存的管理将是比较棘手的的,因为这已经涉及到很多底层的技术了,但是Ehcache为我们做了封装,我们可以很方便地使用Ehcache来进行缓存的管理。
Ehcache可以保存Element对象,这个Element对象本质上是一个key-value的键值对,其中key和value可以使是任意数据类型,这就代表可以用Ehcache来缓存任何类型的数据。
下面将单独Ehcache的配置和使用方式,如果想要看Ehcache和Spring的整合,可以查看:
二、导入jar包
我这里使用的是Ehcache2.10.6这个版本,虽然最新的Ehcache已经发布了3.7,根据情况选择版本;
如果是Maven项目,可以在pom.xml中添加下面的依赖:
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.6</version>
</dependency>
我这里创建的是Java Web项目,所以使用手动导入jar包的方式创建项目。
三、XML方式配置Ehcache
创建一个XML文件,文件名和保存路径随意(只要你能找到就行)。
我这里是在项目的resources下创建一个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="/home/ganlixin/tmp" /> <cache name="cacheOne"
maxBytesLocalDisk="5g" maxBytesLocalHeap="20m" maxBytesLocalOffHeap="200m"
maxEntriesLocalHeap="200" maxEntriesLocalDisk="300"
maxEntriesInCache="500" maxElementsInMemory="1000" eternal="false"
timeToIdleSeconds="60" timeToLiveSeconds="60" overflowToDisk="true"
memoryStoreEvictionPolicy="LRU">
</cache> <cache name="cacheTwo"
maxBytesLocalDisk="5g" maxBytesLocalHeap="20m" maxBytesLocalOffHeap="200m"
maxEntriesLocalHeap="200" maxEntriesLocalDisk="300"
maxEntriesInCache="500" maxElementsInMemory="1000" eternal="false"
timeToIdleSeconds="60" timeToLiveSeconds="60" overflowToDisk="true"
memoryStoreEvictionPolicy="FIFO">
</cache>
</ehcache>
我们上面创建的ehcache.xml配置文件相当于配置了三个“桶”,名称分别是defaultCache、cacheOne、cacheTwo,每一个桶都是一个缓存区域,我们可以将数据放入桶中,实现了数据的缓存。
我们可以创建多个ehcache配置文件,每一个配置文件可以理解为下面这张图。
在缓存数据之前,我们可以自己选择读取哪个ehcache的配置文件(读取不同的配置文件,创建的缓存区域是不一样的),然后根据自己的需求,将数据放入我们指定的桶中。
四、测试使用Ehcache
上面将ehcache配置好后,就可以进行测试了:
package cn.ganlixin.test; import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element; public class Demo { public static void main(String[] args) { // 读取ehcache配置文件,创建cacheManager
CacheManager cacheManager = CacheManager.create("ehcache.xml"); // 利用cacheManager获取指定的cache(相当于指定使用哪个桶来保存数据)
// 如果不指定的话,就会使用默认的defaultCache来存数据
Cache cache = cacheManager.getCache("cacheOne"); // 创建Element,Element是一个key-value形式的,key和value可以是任意数据类型
Element e = new Element("keyOne", "valueOne"); // 将Element放入我们指定的缓存中(也就是cacheOne那个桶中)
cache.put(e); // 通过传入key值,从cache中获得Element
Element e2 = cache.get("keyOne");
System.out.println(e2);
// 获取的Element对象包含多个属性,打印的结果如下:
// [ key = keyOne, value=valueOne, version=1, hitCount=1, CreationTime = 1558015329449, LastAccessTime = 1558015329451 ] // 可以单独的获取Element属性
System.out.println(e2.getObjectKey());
System.out.println(e2.getObjectValue());
System.out.println(e2.getVersion());
System.out.println(e2.getHitCount());
System.out.println(e2.getCreationTime());
System.out.println(e2.getLastAccessTime());
System.out.println(e2.getExpirationTime()); // 移除指定cache中的key对应的Element,移除成功则返回true,如果不存在或者Element已经过期,则返回false
// 注意移除不存在Element,并不会报错
boolean isRemoved = cache.remove("keyOne"); // 替换
Element e3 = cache.replace(e2); // 返回替换前的Element,如果不存在则返回null
boolean isReplaced = cache.replace(e2, e3); // 关闭cacheManager
cacheManager.shutdown();
}
}
五、Ehcache的数据存储
对于Ehcache来说,缓存的数据可以保存自两个地方:内存和磁盘。其中数据存储内存是始终启用的,但是磁盘存储却并没有强制要求,可以自己配置。
对于内存来说,还可以细分,Ehcache将内存分了两类:堆内存和非堆内存。 对于这两类,Ehcache官网是这样描述的:
The memory store is always enabled and exists in heap memory. For the best performance, allot as much heap memory as possible without triggering garbage collection (GC) pauses, and use the off-heap store to hold the data that cannot fit in heap (without causing GC pauses).
翻译过来就是说:尽量扩大堆的容量(保证不会因为堆的容量不足而发生GC,导致停顿),并且尽量将不适合用堆来存储的数据放入非堆内存的区域进行存储。
六、配置文件解析
Ehcache默认的是去项目的类路径(也就是classpath)目录下寻找ehcache.xml文件作为Ehcache的配置文件,但是我们也可以自己指定配置文件的名称和路径,只需要在创建CacheManager的时候保证自己写的路径没有错误即可。
首先知道的是,Ehcache不仅支持我们在XML配置文件中对Ehcache进行配置,同时还支持我们在代码中进行Ehcache的配置(比如创建一个新的cache),但是,好像没有人会这样做,因为一旦将配置写在Java代码中,一旦要修改配置,就需要重新编译一次源码(甚至需要重新编译整个项目),而写在XML中就没有这个问题,只需要重新启动项目即可。
我这里将ehcache.xml分为三部分,然后详细介绍每一部分。
6.1、CacheManager级别
<?xml version="1.0" encoding="UTF-8"?>
<ehcache
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" maxEntriesLocalHeap="2000"
maxEntriesLocalOffHeap="2000"
maxEntriesLocalDisk="3000" maxBytesLocalDisk="5g"
maxBytesLocalHeap="20m"
maxBytesLocalOffHeap="200m" memoryStoreEvictionPolicy="LRU"
>
</ehcache>
maxEntriesLocalHeap属性:在堆中,允许存放的Element最大数量值。
maxEntriesLocalOffHeap属性:在堆外的内存中允许存放的Element的最大数量值。
maxEntriesLocalDisk属性:在磁盘上允许存放的Element的最大数量值,如果设置为0,表示数量没有限制(可能会出现磁盘全部用尽的情况)。
maxBytesLocalDisk属性:指定Ehcache可以在磁盘上占用的空间大小。
maxBytesLocalHeap属性:制定Ehcache可以在堆内存中占用的空间大小。
maxBytesLocalOffHeap属性:指定Ehcache可以在堆外的内存中占用多大的大小。
memoryStoreEvictionPolicy属性:指定回收策略,可以选择:LRU、FIFO、LFU。
上面的这几个属性不仅可以在CacheManager级别配置,还可以在<cache>配置。不过需要注意的是:如果CacheManager级别配置了maxBytesLocalDisk、maxBytesLocalHeap、maxBytesLocalOffHeap这几个属性,那么他下面的每个<cache>也必须配置这些属性,并且<cache>中配置的空间是从CacheManager中扣除的。
6.2、diskStore
<?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="/home/ganlixin/tmp" /> </ehcache>
<diskStore>可以用来配置是否启用磁盘存储,并指定保存的路径。如果启用磁盘存储的话,可以配置当内存中的Element超出限制时,将缓存中的数据写到磁盘中。
6.3、cache级别
<cache name="cacheOne"
maxBytesLocalDisk="5g"
maxBytesLocalHeap="20m"
maxBytesLocalOffHeap="200m" maxEntriesLocalHeap="2000"
maxEntriesLocalDisk="3000" maxEntriesInCache="500"
maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="60"
timeToLiveSeconds="60" overflowToDisk="true"
memoryStoreEvictionPolicy="LRU"
>
<persistence strategy="localTempSwap"/>
</cache>
这一部分的很多属性都和CacheManager级别的属性相同,但是注意<cache>中不能出现MaxEntriesLocalOffHeap,也就是说不能配置堆外内存的大小。
timeToIdleSeconds属性:元素放入cache后,距离上一次被访问的时间超过timeToIdleSeconds秒,元素就会被清除。如果设置为0,则表示距离上一次被访问的时间超过timeToIdleSeconds秒,元素也不会被清除。
timeToLiveSeconds属性:距离该元素放入cache时间超过了timeToLiveSeconds秒,元素就会被清除,及时在此此件被访问过多次,依旧会被清除。如果设置为0,则表示即使距离放入元素的时间超过timeToLiveSeconds秒,元素也不会被清除。
eternal属性:是否设置元素的生命周期为无限。如果设置为true,则表示即使超过设置的timeToIdleSeconds或者timeToLiveSeconds,元素也不会内清除(此时timeToIdleSeconds和timeToLiveSeconds相当于设置为0)。
overflowToDisk属性:当内存中已经存放不下元素的时候(设置的内存大小不足),是否选择将元素保存到磁盘中。
memoryStoreEvictionPolicy属性:cache中元素的回收策略。
<persistence strategy="localTempSwap" /> 表示使用cache期间,会使用本地的磁盘交换空间,但是存在这上面的数据并不能真正持久化(一旦重启就消失了)。
七、与Spring框架的整合
这个可以参考:Spring整合Ehcache
Ehcache 学习入门的更多相关文章
- ehcache缓存入门学习
ehcache缓存入门学习 1,概念 特性 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. 主要的特性有:1. 快速2 ...
- 每天成长一点---WEB前端学习入门笔记
WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...
- C# BackgroundWorker组件学习入门介绍
C# BackgroundWorker组件学习入门介绍 一个程序中需要进行大量的运算,并且需要在运算过程中支持用户一定的交互,为了获得更好的用户体验,使用BackgroundWorker来完成这一功能 ...
- 给深度学习入门者的Python快速教程 - 番外篇之Python-OpenCV
这次博客园的排版彻底残了..高清版请移步: https://zhuanlan.zhihu.com/p/24425116 本篇是前面两篇教程: 给深度学习入门者的Python快速教程 - 基础篇 给深度 ...
- 给深度学习入门者的Python快速教程 - numpy和Matplotlib篇
始终无法有效把word排版好的粘贴过来,排版更佳版本请见知乎文章: https://zhuanlan.zhihu.com/p/24309547 实在搞不定博客园的排版,排版更佳的版本在: 给深度学习入 ...
- UML学习入门就这一篇文章
1.1 UML基础知识扫盲 UML这三个字母的全称是Unified Modeling Language,直接翻译就是统一建模语言,简单地说就是一种有特殊用途的语言. 你可能会问:这明明是一种图形,为什 ...
- Stanford Parser学习入门(2)-命令行运行
在Stanford parser目录中已经定义了一部分命令行工具以及图形界面,本文将介绍如何在windows使用这些工具进行语法分析,Linux下也有shell可以使用. 关于如何搭建环境请参考上一篇 ...
- Python学习入门基础教程(learning Python)--5.6 Python读文件操作高级
前文5.2节和5.4节分别就Python下读文件操作做了基础性讲述和提升性介绍,但是仍有些问题,比如在5.4节里涉及到一个多次读文件的问题,实际上我们还没有完全阐述完毕,下面这个图片的问题在哪呢? 问 ...
- 深度学习入门实战(二)-用TensorFlow训练线性回归
欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 作者 :董超 上一篇文章我们介绍了 MxNet 的安装,但 MxNet 有个缺点,那就是文档不太全,用起来可能 ...
随机推荐
- 「资料分享」理解uboot要看哪些书
最开始是看的韦东山老师的视频,确实很不错,不过总感觉是不够深入扎实,还是想自己看看书,就总结搜罗下,以供参考 学习交流可以添加 微信读者交流①群 (添加微信:coderAllen) 程序员技术交流①群 ...
- 查找正在运行的nginx目录
linux系统因为备份.不同版本等问题,导致ECS Linux上存放有多个Nginx目录,可以通过如下方法定位当前正在运行的Nginx的配置文件: 1. 查看nginx的PID,以常用的80端口为例: ...
- supervisor安装部署文档和管理实例
Supervisord是用Python实现的一款非常实用的进程管理工具,类似于monit(关于monit见我的博客:用monit监控系统关键进程),monit和supervisord的一个比较大的差异 ...
- python笔记36-装饰器之wraps
前言 前面一篇对python装饰器有了初步的了解了,但是还不够完美,领导看了后又提出了新的需求,希望运行的日志能显示出具体运行的哪个函数. __name__和doc __name__用于获取函数的名称 ...
- test20190905 ChiTongZ
100+22+90=212.前两道题不错,但T3 没什么意义. 围观刘老爷超强 T1 解法. ChiTongZ的水题赛 [题目简介] 我本可以容忍黑暗,如果我不曾见过太阳. 考试内容略有超纲,不超纲的 ...
- Pycharm中打开Terminal方式
点击剪头的图标就可以在左侧出现Terminal
- C++指针的一些问题
用变量a给出下面的定义: a)一个整形数(An integer) b)一个指向整形数的指针 c)一个指向指针的指针,它指向的指针指向一个整形数 d)一个有十个整形数的数组 e)一个有十个指针的数组,该 ...
- fitnesse wiki界面设置变量
有时候我们可能多组测试数据会到同一个值,这样我们就可以设置一个变量,修改时只需要修改一个地方即可,而不需要对每组测试数据的这列数据进行修改 如下图: (1)定义变量:!define A {10} , ...
- LeetCode 842. Split Array into Fibonacci Sequence
原题链接在这里:https://leetcode.com/problems/split-array-into-fibonacci-sequence/ 题目: Given a string S of d ...
- 【洛谷P5158】 【模板】多项式快速插值
卡常严重,可有采用如下优化方案: 1.预处理单位根 2.少取几次模 3.复制数组时用 memcpy 4.进行多项式乘法项数少的时候直接暴力乘 5.进行多项式多点求值时如果项数小于500的话直接秦九昭展 ...