【精品】JDK17下使用Ehcache3
Ehcache简介
Ehcache 是一个开源的高性能缓存,拥有很高的拓展性和伸缩性,广泛使用各种 Java 项目中(如 Hibernate 默认使用 Ehcache作为二级缓存),在目前基于 Java 的缓存方案里,几乎是性能最高的实现。
Ehcache 官网:http://www.ehcache.org
Ehcache 3.X 技术文档:http://www.ehcache.org/documentation/
Ehcache架构:
Ehcache的特点:
- 缓存数据有三级:内存、堆外缓存Off-Heap、Disk缓存,因此无需担心容量问题。还可以通过RMI、可插入API等方式进行分布式缓存。
- 缓存数据会在虚拟机重启的过程中写入磁盘,持久化。
- 具有缓存和缓存管理器的侦听接口。
- 支持多缓存管理器实例,以及一个实例的多个缓存区域。
Ehcache3支持堆、堆外、磁盘以及集群缓存;除了堆之外的三种缓存,缓存的键值对必须支持序列化和反序列化。我们在使用的时候,可以单独使用任意一个。
- heap :堆上存储,利用Java的堆上RAM内存来存储缓存条目。该层使用与Java应用程序相同的堆内存
- off-heap: 堆外内存,大小仅受可用RAM限制。不受Java垃圾回收(GC)的约束。与堆上存储相比,它速度较慢,因为在存储和重新访问JVM堆时必须将数据移入和移出JVM堆。
- disk:利用磁盘(文件系统)存储缓存条目。存储空间充足,但比基于RAM的存储要慢得多。对于所有使用磁盘存储的应用程序,建议使用快速专用磁盘来优化吞吐量。
- clustered:群集存储,该数据存储是远程服务器上的缓存。
使用
- 常被查询、最重要、数据量较小的数据存放在堆缓存,不用担心JVM的重启,有持久化机制;
- 常被查询、数据量中等的数据存放在堆外缓存,几个G就好了,不用担心服务器的重启,有持久化机制;
- 不常用、大量的数据、但又不想占用数据库IO的数据,放在Disk缓存,容量自便;
如果要使用多个层,则必须遵守一些约束条件:
- 必须始终有堆内存
- disk和clusterd不能同时存在
- 层的大小应采用金字塔式的大小,即,金字塔较高的层配置为使用的内存比下方较低的层少。
可能出现的层组合:
- heap + offheap
- heap + offheap + disk
- heap + offheap + clustered
- heap + disk
- heap + clustered
注意:
- 将值放入高速缓存时,它会直接进入最低层,比如heap + offheap + disk直接会存储在disk层。
- 当获取一个值,从最高层获取,如果没有继续向下一层获取,一旦获取到,会向上层推送,同时上层存储该值。
小知识:堆外缓存 |
---|
堆外缓存(off-heap)既是独立的进程缓存,又是JVM堆外的系统缓存。JVM堆是非常宝贵的,如果占用过大会带来GC性能问题,堆外缓存很好的解决了这个问题。现在服务器内存越来越大,而磁盘缓存的io性能又比较低,off-heap缓存就是折中的方案,既保证了高速性能,又可以有一定的容量。off-heap缓存性能的占用主要是序列化、反序列化的过程。一旦对象被序列化,在返回Java堆的时候必需反序列化才可以使用。这是一笔较大的性能开销。但off-heap还是要比本地磁盘、网络存储、RDBMS数据库IO等记录数据的系统要快的多。还应指出的是,序列化/反序列化的性能开销远没有很多用户想象的那么大。off-heap已经针对字节缓冲区做了优化,本身也包含一些优化机制,可以对使用标准Java序列化的对象进行优化,能使复杂Java对象的性能提升两倍,使byte数组的性能提升四倍。 |
示例
备注:由于JDK17的原因,xml配置方式使用Ehcache会报各种莫名其妙的问题,基本上没有研究的意义,所以下面示例只讲了Java代码的方式。
Maven依赖:
<dependency><groupId>org.ehcache</groupId><artifactId>ehcache</artifactId><version>3.10.0</version>
</dependency>
<dependency><groupId>javax.cache</groupId><artifactId>cache-api</artifactId><version>1.1.1</version>
</dependency>
测试代码一:创建CacheManager的同时指定Cache
@Test
public void fun1() {CacheManager manager = CacheManagerBuilder.newCacheManagerBuilder().withCache("myCache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class, ResourcePoolsBuilder.heap(100).build())).build(true);//通过别名获取缓存Cache<Integer, String> cache = manager.getCache("myCache", Integer.class, String.class);cache.put(1001, "haha");String value = cache.get(1001);System.out.println(value);// 移除一个给定的Cache,CacheManager不仅会删除它对Cache的引用,而且还会关闭它。manager.removeCache("myCache");// 关闭CacheManager提供的所有临时资源。manager.close();
}
在cacheManager中检索Cache,需要通过别名、键类型,值类型。比如,要获得第2步中声明的缓存,您需要它的别名=“myCache”,keyType=Integer.class和valueType = String.class。出于类型安全考虑,我们要求键和值类型都要传递。如果这些和我们期望的不同CacheManager将会在应用程序生命周期的早期抛出一个ClassCastException这可以保护缓存免受随机类型的污染。
put()方法用来往Cache中添加内容,其中:第一个参数是键,第二个参数是值。键和值类型必须是与在cacheconfig容器中定义的类型相同的类型。另外,键必须是惟一的,并且只与一个值相关联。
get(key)方法用来从缓存中检索值。它只需要一个参数,这个参数是键,然后返回与该键关联的值。如果没有与该键相关联的值,则返回null。
测试代码二:
@Test
public void fun2() {CacheManager manager = CacheManagerBuilder.newCacheManagerBuilder().build(true);//创建Cache实例CacheConfigurationBuilder<Integer, String> builder = CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class,ResourcePoolsBuilder.heap(10) //堆内缓存,速度最快.offheap(2, MemoryUnit.MB) // 堆外内存,速度低于 heap,但是高于 disk// .disk(1, MemoryUnit.GB) //磁盘缓存,速度最低,相对于 heap和off-heap,disk可以分配大量资源空间).withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(10)));Cache<Integer, String> cache = manager.createCache("myCache", builder);//写缓存cache.put(1001, "xixi");//读缓存String value = cache.get(1001);System.out.println(value);manager.removeCache("myCache");//关闭资源manager.close();
}
测试代码三:将数据缓存到本地硬盘上
@Test
public void fun4() {CacheManager manager = CacheManagerBuilder.persistence("d:/CacheData") //硬盘缓存文件位置.builder(CacheManagerBuilder.newCacheManagerBuilder()).build();manager.init();//创建Cache实例CacheConfigurationBuilder<Integer, String> builder = CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class,ResourcePoolsBuilder.heap(10));Cache<Integer, String> cache = manager.createCache("myCache", builder);//写缓存cache.put(1001, "xixi");//读缓存String value = cache.get(1001);System.out.println(value);manager.removeCache("myCache");//关闭资源manager.close();
}
测试代码四:
@Test
public void fun3() {UserManagedCache<Integer, String> cache = UserManagedCacheBuilder.newUserManagedCacheBuilder(Integer.class, String.class).build(false);cache.init();//写cache.put(11, "aa");//读String value = cache.get(11);System.out.println(value);cache.close();
}
【精品】JDK17下使用Ehcache3相关推荐
- JDK17下没有jre怎么办
java17.0.2使用JDK自带的JRE即可,不需要额外安装JRE. 系统变量只需要配置[Path]即可,其他不需要配置. 若无法使用,最好将bin目录上移到最上面,避免有其它冲突的java环境变量 ...
- js textarea换行
利用html换行符或. 查看全文 http://www.taodudu.cc/news/show-4947167.html 相关文章: textarea 标签内换行 [解决回车键出现乱码的问题]禁用E ...
- JDK17的下载安装与配置(详细教程)
1.搜索JDK的官方网址 https://www.oracle.com/java/technologies/downloads/#jdk17 2.切换到window系统,根据自己电脑的系统进行切换.然 ...
- Java中jdk1.8和jdk17相互切换
之前做Java项目时一直用的是jdk1.8,现在想下载另一个jdk版本17,并且在之后的使用中可以进行相互切换,我将jdk切换时所遇到的问题记录下来并分享出来供大家参考. 1.环境变量中之前已经配置好 ...
- 5月份Qoo10单品观察:月营收超 $92,074.5的宝宝湿巾(下)
上一篇文章其实非常重要,不管你是Qoo10大卖家,还是打算做Qoo10的新手,你都应该重视目前平台电商运营的变化趋势,为什么? 因为平台大宗商品类目早就饱和了,你再绞尽脑汁的去挖掘什么产品好卖,去拓展 ...
- java分布式dubbo_Dubbo剖析-搭建一个简单的分布式系统(1)
一.前言 随着阿里巴巴开源的分布式RPC框架Dubbo成为Apache开源卵化器项目,Dubbo有火了一把.在接下来的一段时间本公众号将会时不时的发布一些dubbo使用与原理剖析的文章. image. ...
- JVM类加载、验证、准备、解析、初始化、卸载过程详解
目录 0 使用类的准备工作 初始化(Init) 1 加载(Load) 1.1 详细过程 1.1.1 通过类全限定名获取该类的二进制字节流 1.1.2 静态存储结构=>运行时数据结构 1.1.3 ...
- 4月11号软件资讯更新合集......
跟 ChatGPT 聊天.需求润色优化,禅道 OpenAI 插件发布! 禅道插件上新了,OpenAI 禅道集成,可提供神奇海螺聊天.需求润色功能. 神奇海螺 "章鱼哥,你为什么不问问神奇海螺 ...
- MOOC课程信息D3.js动态可视化
版权声明:本文为博主原创文章,转载 请注明出处:https://blog.csdn.net/sc2079/article/details/83153693 - 写在前面 好久没更新博客了,主要还是最近 ...
最新文章
- 01:谁考了第k名 个人博客:doubleq.win
- EL表达式介绍(1)
- 借收购搭桥,风河Workbench软件环境涵盖至测试领域
- springboot集成restTemplate实现rest接口调用
- 网站移动版本开发踩坑实录二
- 2019.2.4 nfs原理和安装实验
- .NET的两种部署模式,了解一下
- Ubuntu nginx+uwsgi部署Django项目
- Win10 Ubuntu子系统用户密码忘记解决方案
- 6个用于大数据分析的最好工具(转)
- 个人博客网页设计_不会代码如何打造个人博客?你需要这个简单、免费的搭建工具...
- Leetcode-148-排序链表(递归+迭代)
- impala查询语句_impala 下的SQL操作
- view绘制流程学习心得
- 算法:eight Queens 8皇后问题
- pycharm 远程连接Linux
- 正确安装vray5 for 3dsMax步骤
- 《第一行代码Android(第3版)》— Android 书籍
- 缩写月份单词python代码_Python替换月份为英文缩写的实现方法
- UE4 材质学习 (01-第一个材质)