`
kavy
  • 浏览: 891272 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

基于EHCache实现缓存去重

 
阅读更多

 由于近期的工作主要集中在数据处理上,而性能问题时而暴露出来,我对需要处理的数据进行了一下简单的分析,发现存在大量的重复数据,这自然让我想到了去建立一个二级缓存把曾经处理过的数据缓存起来,避免重复处理。我们业务上其实就是对最近处理过的数据重复出现几率比较高,所以有一个几百兆的内存空间用LRU的策略进行去重应该就足够了。

    其实可以选择的方案有很多,初步筛选了一下,我决定在对Java支持度比较好且应用广泛的OSCache和EHCache中选一个。上了官网一查,发现OSCache在几年前就停止更新了,而EHCache则一直有公司在维护,所以自然选定了后者。官方文档的地址是http://www.ehcache.org/documentation/index.html

    先让同事研究了一下,弄的是1.7.0的版本,这个版本比较好的是对其他包的依赖很少,很快就把自己的demo建立起来了。然后上官网下载了最新的版本ehcache-core-2.3.1-distribution,里面其实就多了两个slf4j的包,原来的代码一行没动就可以运行起来了。这里新版本加入的内容比较多,jar包就是1.7.0的3倍大,看了下官方文档的说明,主要加入的就是对分布式的支持,当然还有很多新特性。新特性以后慢慢研究吧,我目前也用不到什么高级功能,既然新版本使用起来也很方便,那就用这个好了。

    这里简单解释一下,我们原先想试一下他提供的FIFO和LRU的策略,结果刚开始测试输出的结果和预期居然不一致,官方文档上也没看到相应的解释。经过反复测试,感觉他不是严格按照这个策略来,可能是算法有些问题吧。

    另外补充一下参数设置的经验。

  1. 对于存储对象个数的设置:由于配置文件中只能指定maxElementsInMemory,这就会有可能存入的对象太多而超出VM的heap大小,当然你可以通过jvm参数增大heap大小,但这总还是有可能溢出。这里可以把maxElementsInMemory值设置到一个比较安全的大小,自己预先测试一下最好。如果内存仍然存不下你需要存的对象个数,那么可以开启overflowToDisk来增加可以存储的Element个数。这里要注意一下,EHCache不会自动帮助你去把内存对象写入到磁盘,当超过maxElementsInMemory程序会自动把更多的部分开始往硬盘写,但是内存的对象其实并没有清出去,这时需要手动使用Cache.flush()方法来把内存对象清出去。 对于是否需要用磁盘扩充缓存,这个还是根据自己应用判断。
  2. 重建上一次运行的缓存:这个需求肯定比较普遍,我们当然不希望一旦程序退出,整个缓存就要重建了。开启diskPersistent功能,只要使用的是CacheManager单例模式,下一次启动的时候就会调用上一次运行的缓存。比较麻烦的是写入磁盘的时间还是要自己调用 Cache.flush()方法。如果仅仅考虑到程序重启的话,我建议这里把diskStore写入到一个ramfs,这样性能就更高了,但重启电脑的话就不得不重建缓存了。
  3. 索引的建立:如果你测试的maxElementsOnDisk量比较大的话,我本地设置成100000,那么你会在临时文件目录下看到有index文件,这个文件显然是对磁盘上的文件建立索引,加快查询速度。所以这个索引是否建立是EHCache自动帮你做的,你不用操心了。
  4. 写入缓存的速度:在本地不断调整参数,惊讶的发现有时写入缓存的速度奇慢。因为开启了 diskPersistent功能,程序运行时经常会卡在backOffIfDiskSpoolFull方法上,作用是If the disk store spool is full wait a short time to give it a chance to catch up。这个参数对应的是diskSpoolBufferSizeMB,默认是30MB,如果存储的对象比较多,强烈建议调大,或者直接把 diskPersistent关掉。
  5. 缓存内容写入磁盘的速度:如果你把maxElementsOnDisk参数配置的远小于maxElementsInMemory值的话,你会发现速度又变得很慢,这是因为程序一直要去找到底哪些内容应该写入磁盘。建议这 maxElementsOnDisk值的配置应该不小于 maxElementsInMemory,其实正常用应该也会这么配置,只是我测试无聊试了下出问题了。
  6. 内存Element数量不能控制:一旦开启了 diskPersistent,惊讶的发现居然设置的 maxElementsInMemory无效了,内存的 Element数量一直在增长。反复测试,问题稳定重现,又找不到解释,无奈之下给官方提了个bug,等答复吧,汗...

 

     这里还是给出测试代码,主要用到的就是一个ehcache.xml的配置文件,定义了Cache的具体策略。程序调用的时候非常方便,就是典型key/value的方式。

  1. <?xml version="1.0" encoding="UTF-8"?> 
  2. <ehcache> 
  3.  
  4.     <diskStore path="java.io.tmpdir" /> 
  5.      
  6.     <defaultCache  
  7.         maxElementsInMemory="10000"  
  8.         eternal="false" 
  9.         timeToIdleSeconds="120"  
  10.         timeToLiveSeconds="120"  
  11.         overflowToDisk="true" 
  12.         diskPersistent="false"  
  13.         diskExpiryThreadIntervalSeconds="120" 
  14.         memoryStoreEvictionPolicy="LRU"  
  15.     /> 
  16.          
  17.     <cache name="sample"          
  18.         maxElementsInMemory="5"   
  19.         maxElementsOnDisk = "5"  
  20.         eternal="false"   
  21.         timeToIdleSeconds="1440"   
  22.         diskPersistent="false"  
  23.         timeToLiveSeconds="2880"   
  24.         overflowToDisk="false"  
  25.         memoryStoreEvictionPolicy="FIFO"  
  26.         statistics="true"  
  27.     /> 
  28.  
  29. </ehcache> 

    以下就是测试代码:

  1. package ehcache; 
  2.  
  3. import org.apache.log4j.Logger; 
  4.  
  5. import net.sf.ehcache.Cache; 
  6. import net.sf.ehcache.CacheManager; 
  7. import net.sf.ehcache.Element; 
  8.  
  9. public class EhcacheTest { 
  10.      
  11.     private static final Logger logger = Logger.getLogger(EhcacheTest.class); 
  12.      
  13.     private static Cache sampleCache = null
  14.      
  15.     public static void main(String[] args) { 
  16.         init(); 
  17.         test(); 
  18.     } 
  19.  
  20.     private static void test() { 
  21.         logger.info(sampleCache.getMemoryStoreEvictionPolicy()); 
  22.         for(int i=0; i<10; i++){ 
  23.             //写入缓存 
  24.             sampleCache.put(new Element(i, "v" + i)); 
  25.             //打印当前缓存的所有值 
  26.             logger.info(sampleCache.getKeys()); 
  27.             //读取缓存 
  28.             Element e = sampleCache.get(i); 
  29.             logger.info(e.getValue()); 
  30.         } 
  31.         //打印命中统计 
  32.         logger.info(sampleCache.getStatistics()); 
  33.     } 
  34.      
  35.     private static void init() { 
  36.         CacheManager manager = CacheManager.create(); 
  37. //      manager.addCache("sample"); //已经在配置文件定义过了 
  38.         sampleCache = manager.getCache("sample"); 
  39.     } 
  40.  
转自:http://passover.blog.51cto.com/2431658/486709
分享到:
评论

相关推荐

    SpringBoot 集成Ehcache实现缓存

    ### Spring Boot集成Ehcache实现缓存 #### 一、Ehcache简介 Ehcache是一个高效的纯Java进程内缓存框架,以其快速且轻便的特点而被广泛应用于各种应用场景中,尤其在Java EE和轻量级容器环境中更是受到青睐。...

    Ehcache分布式缓存与其在SpringBoot应用

    Ehcache是一个高性能的、基于Java的进程内缓存解决方案,它被广泛应用于各种Java应用程序,包括Java EE和轻量级容器。Ehcache的主要优势在于它的快速响应、易用性和丰富的缓存策略。它提供了两种级别的缓存存储:...

    Spring 与Ehcache实现基于方法的缓存

    本篇文章将详细探讨如何在Spring框架中集成并实现基于方法的缓存机制,利用Ehcache来优化数据访问。 首先,我们需要理解Spring的AOP概念,AOP允许我们定义横切关注点,如日志、事务管理或,正如在这个案例中,缓存...

    基于java的开发源码-Ehcache Java 缓存框架.zip

    基于java的开发源码-Ehcache Java 缓存框架.zip 基于java的开发源码-Ehcache Java 缓存框架.zip 基于java的开发源码-Ehcache Java 缓存框架.zip 基于java的开发源码-Ehcache Java 缓存框架.zip 基于java的开发源码-...

    ehcache项目缓存技术

    Ehcache是Java平台上的一个开源、高性能的分布式缓存系统,它在处理大量用户访问主页或频繁操作某些数据时,能显著提升系统的响应速度和效率。本篇文章将深入探讨Ehcache项目的缓存技术及其应用。 一、Ehcache简介...

    springboot+mybatis+ehcache实现缓存数据

    在本文中,我们将深入探讨如何使用SpringBoot、MyBatis和Ehcache来实现缓存数据。Ehcache是一款高效且易于使用的Java内存缓存框架,对于提升应用程序性能,尤其是在处理大量数据时,能起到显著作用。虽然在分布式...

    ehcache页面缓存技术

    ehcache页面缓存技术ehcache页面缓存技术ehcache页面缓存技术ehcache页面缓存技术ehcache页面缓存技术ehcache页面缓存技术ehcache页面缓存技术ehcache页面缓存技术ehcache页面缓存技术ehcache页面缓存技术ehcache...

    Spring Boot中使用EhCache实现缓存支持

    ### Spring Boot中使用EhCache实现缓存支持 #### 概述 在现代软件开发过程中,缓存技术已经成为提升系统性能的重要手段之一。通过减少对底层数据存储的频繁访问,缓存可以有效缓解数据库压力,加快应用响应速度。...

    Hibernate + EhCache 实现数据缓存的处理

    总结起来,本文介绍了如何结合Hibernate和EhCache实现数据缓存,涉及了Hibernate配置、EhCache配置、实体类缓存注解以及缓存功能的测试。理解并实践这些知识点,有助于开发出更高效、响应更快的Java应用。

    高并发缓存器(基于ehcache)

    **高并发缓存器(基于ehcache)** 在IT行业中,面对高并发场景时,缓存技术是提高系统性能和响应速度的关键手段。基于ehcache的缓存器是一种常见的解决方案,它能够在内存中存储常用数据,减少对数据库的访问,从而...

    基于java的开发源码-ehcache(Java缓存框架 EhCache).zip

    基于java的开发源码-ehcache(Java缓存框架 EhCache).zip 基于java的开发源码-ehcache(Java缓存框架 EhCache).zip 基于java的开发源码-ehcache(Java缓存框架 EhCache).zip 基于java的开发源码-ehcache(Java缓存框架 ...

    37. Spring Boot集成EHCache实现缓存机制【从零开始学Spring Boot】

    在本教程中,我们将深入探讨如何使用Spring Boot集成EHCache来实现高效的缓存机制。Spring Boot简化了配置过程,使得我们可以快速地将EHCache引入到我们的应用中,从而提高应用程序的性能,减少对数据库或其他资源的...

    基于JGROUPS的ehcache的分布式缓存复制

    本文将深入探讨基于JGROUPS的Ehcache实现的分布式缓存复制,这是一种在Java应用中广泛使用的缓存解决方案。 首先,Ehcache是一个开源的、高性能的Java缓存库,提供本地缓存以及分布式缓存功能。它支持多种缓存策略...

    集群环境中使用_EhCache_缓存系统&Ehcache配置文件的详细说明

    在集群环境中,EhCache通过RMI(远程方法调用)或JGroups协议实现节点间的通信,保证了缓存数据的一致性。 二、EhCache在集群环境中的应用 1. 数据共享:在集群环境中,多个服务器节点可以共享同一份缓存数据,减少...

    项目优化之Ehcache页面缓存

    Ehcache基于Key-Value的数据结构,当一个对象被缓存时,会通过Key进行唯一标识。Ehcache内部采用分段(Segment)技术,每个段独立负责一部分Key的存储。当请求到来时,Ehcache会先在内存中查找,如果找不到,则会...

    详解springboot整合ehcache实现缓存机制

    SpringBoot整合Ehcache实现缓存机制 SpringBoot是一款近年来非常流行的Java框架,提供了快速的集成方式来简化新Spring应用的初始搭建以及开发过程。Ehcache是一个纯Java的进程内缓存框架,具有快速、精干等特点,是...

    ehcache分布式缓存实例

    本实例将探讨如何利用Ehcache实现基于RMI(Remote Method Invocation)的分布式缓存。 一、Ehcache简介 Ehcache是Terracotta公司开发的一个高性能、可伸缩的本地和分布式缓存解决方案。它支持多种缓存策略,如LRU...

    Ehcache分布式缓存入门案例demo_文件转树结构_

    本入门案例将带你了解如何使用Ehcache实现分布式缓存,并特别关注如何将文件数据转换为树形结构。 首先,让我们理解Ehcache的基本概念。Ehcache的核心组件包括缓存管理器(Cache Manager)、缓存(Cache)和缓存项...

    Spring AOP+ehCache简单缓存系统解决方案

    在本篇【Spring AOP+ehCache简单缓存系统解决方案】中,我们将探讨如何利用Spring AOP(面向切面编程)和ehCache框架来构建一个高效、简单的缓存系统,以提升应用程序的性能。ehCache是一款流行的开源Java缓存库,它...

    细谈Ehcache页面缓存的使用

    ### 细谈Ehcache页面缓存的使用 在当今高度动态且数据密集型的应用环境中,缓存技术扮演着至关重要的角色。Ehcache作为一款高性能、轻量级的Java缓存框架,被广泛应用于各种场景中以提高系统的响应速度和整体性能。...

Global site tag (gtag.js) - Google Analytics