Java缓存Ehcache-Ehcache的Cache预热机制及代码实现(Cache Warming for multi-tier Caches)

Ehcache中Cache预热机制

Cache预热机制简介

Ehcache在程序启动的时候并不会立即去加载位于磁盘上的数据到内存,而是在数据被用到的时候去加载(lazy load)。因此在cache启动的时候,其内部没有数据。如果我们想在用到这些数据之前,它们全部被装载进内存,应该怎么做?


Ehcache提供了BootstrapCacheLoader机制来解决这个问题,在Cache被激活之前,它会得到运行。并且有两种模式:同步和异步。如果是同步模式,在CacheMana启动之前,加载便会完成;如果是异步模式,在CacheManager启动的时候,加载会在后台继续,而不是等到所需数据被需要的时候。


具体实现

我们只需要实现接口BootstrapCacheLoader定义自己的加载器MyBootstrapCacheLoader,继承BootstrapCacheLoaderFactory实现一个具体的加载工厂MyBootstrapCacheLoaderFactory即可实现数据的预热。

MyBootstrapCacheLoader负责实现怎么将数据加载进Cache,我们可以进行个性化的实现。MyBootstrapCacheLoaderFactory是一个具体的加载工厂,负责创建加载器实例,我们需要实现一些抽象方法。


下面看具体的代码实现(Java)。

MyBootstrapCacheLoader.java:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  *  
  3.  * Copyright (c) 2004-2014 All Rights Reserved. 
  4.  */  
  5. package com..test.encache;  
  6.   
  7. import java.util.List;  
  8.   
  9. import net.sf.ehcache.CacheException;  
  10. import net.sf.ehcache.Ehcache;  
  11. import net.sf.ehcache.Element;  
  12. import net.sf.ehcache.bootstrap.BootstrapCacheLoader;  
  13.   
  14. import org.slf4j.Logger;  
  15. import org.slf4j.LoggerFactory;  
  16.   
  17. /** 
  18.  *  
  19.  * @author  
  20.  * @version $Id: CustomBootstrapCacheLoader.java, v 0.1 2014年10月18日 上午10:57:26  Exp $ 
  21.  */  
  22. public class MyBootstrapCacheLoader implements BootstrapCacheLoader {  
  23.     private static final Logger logger = LoggerFactory  
  24.                                            .getLogger(MyBootstrapCacheLoaderFactory.class);  
  25.   
  26.     StatesDAO                   statesDAO;  
  27.   
  28.     boolean                     asynchronous;  
  29.   
  30.     /**  
  31.      * @see net.sf.ehcache.bootstrap.BootstrapCacheLoader#load(net.sf.ehcache.Ehcache) 
  32.      */  
  33.     public void load(Ehcache cache) throws CacheException {  
  34.         logger.info("load your cache with whatever you want....");  
  35.   
  36.         List keys = cache.getKeys();  
  37.         for (int i = 0; i < keys.size(); i++) {  
  38.             logger.info("keys->" + keys.get(i));  
  39.         }  
  40.   
  41.         try {  
  42.             List<String> dataList = getStatesDAO().findAllStates();  
  43.             cache.put(new Element(CacheConstants.KEY_ARRAY[0], dataList.get(0)));  
  44.             cache.put(new Element(CacheConstants.KEY_ARRAY[1], dataList.get(1)));  
  45.   
  46.         } catch (Exception e) {  
  47.             // TODO Auto-generated catch block   
  48.             e.printStackTrace();  
  49.         }  
  50.   
  51.         logger.info("load end....");  
  52.     }  
  53.   
  54.     /**  
  55.      * @see net.sf.ehcache.bootstrap.BootstrapCacheLoader#isAsynchronous() 
  56.      */  
  57.     public boolean isAsynchronous() {  
  58.         return asynchronous;  
  59.     }  
  60.   
  61.     /**  
  62.      * @see java.lang.Object#clone() 
  63.      */  
  64.     @Override  
  65.     public Object clone() throws CloneNotSupportedException {  
  66.   
  67.         return super.clone();  
  68.   
  69.     }  
  70.   
  71.     public StatesDAO getStatesDAO() {  
  72.         return statesDAO;  
  73.     }  
  74.   
  75.     public void setStatesDAO(StatesDAO statesDAO) {  
  76.         this.statesDAO = statesDAO;  
  77.     }  
  78.   
  79.     /** 
  80.      * Setter method for property <tt>asynchronous</tt>. 
  81.      *  
  82.      * @param asynchronous value to be assigned to property asynchronous 
  83.      */  
  84.     public void setAsynchronous(boolean asynchronous) {  
  85.         this.asynchronous = asynchronous;  
  86.     }  
  87.   
  88. }  


MyBootstrapCacheLoaderFactory.java

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  *  
  3.  * Copyright (c) 2004-2014 All Rights Reserved. 
  4.  */  
  5. package com.test.encache;  
  6.   
  7. import java.util.Properties;  
  8.   
  9. import net.sf.ehcache.bootstrap.BootstrapCacheLoader;  
  10. import net.sf.ehcache.bootstrap.BootstrapCacheLoaderFactory;  
  11.   
  12. import org.slf4j.Logger;  
  13. import org.slf4j.LoggerFactory;  
  14. import org.springframework.beans.factory.annotation.Autowired;  
  15.   
  16. /** 
  17.  * bootstrap cache loader 
  18.  *  
  19.  * @author  
  20.  * @version $Id: MyBootstrapCacheLoaderFactory.java, v 0.1 2014年10月17日 下午8:02:55  Exp $ 
  21.  */  
  22. public class MyBootstrapCacheLoaderFactory extends BootstrapCacheLoaderFactory {  
  23.     private final String ASYNCHRONOUS_PROPERTY_KEY = "ASYNCHRONOUS";  
  24.   
  25.     @Autowired  
  26.     private StatesDAO    statesDAO;  
  27.   
  28.     public MyBootstrapCacheLoaderFactory() {  
  29.         super();  
  30.         // TODO Auto-generated constructor stub   
  31.     }  
  32.   
  33.     private static final Logger logger = LoggerFactory  
  34.                                            .getLogger(MyBootstrapCacheLoaderFactory.class);  
  35.   
  36.     @Override  
  37.     public BootstrapCacheLoader createBootstrapCacheLoader(Properties properties) {  
  38.         logger.info("MyBootstrapCacheLoaderFactory : create a BootstrapCacheLoader");  
  39.         MyBootstrapCacheLoader loader = new MyBootstrapCacheLoader();  
  40.         statesDAO = new StatesDAO();  
  41.         loader.setStatesDAO(statesDAO);  
  42.         loader.setAsynchronous(getAsyncFromProperty(properties));  
  43.   
  44.         return loader;  
  45.     }  
  46.   
  47.     private boolean getAsyncFromProperty(Properties properties) {  
  48.         String asynchronous = properties.getProperty(ASYNCHRONOUS_PROPERTY_KEY);  
  49.   
  50.         return Boolean.valueOf(asynchronous);  
  51.     }  
  52. }  




使用了Cache的读取磁盘数据的方法在StatesDAO类中,对此我们只是进行了模拟,从数据库中读取数据。

StatesDAO.java

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  *  
  3.  * Copyright (c) 2004-2014 All Rights Reserved. 
  4.  */  
  5. package com.test.encache;  
  6.   
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. import com.googlecode.ehcache.annotations.Cacheable;  
  11.   
  12. /** 
  13.  *  
  14.  * @author  
  15.  * @version $Id: StatesDAO.java, v 0.1 2014年10月17日 下午8:07:05  Exp $ 
  16.  */  
  17. public class StatesDAO {  
  18.     //annotation based caching and the name of cache should be defined in ehcache.xml.   
  19.   
  20.     @Cacheable(cacheName = "stateCache")  
  21.     public List<String> findAllStates() {  
  22.         List<String> dataList = new ArrayList<String>();  
  23.   
  24.         //your call to database that returns a list of objects    
  25.         dataList.add("value1");  
  26.         dataList.add("value2");  
  27.   
  28.         return dataList;  
  29.     }  
  30. }  
Cache配置myehcache.xml:

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. <ehcache>  
  2.   
  3. <diskStore path="D://localcache"/>  
  4.   
  5. <cache   
  6.     name="stateCache"   
  7.     maxEntriesLocalHeap="10000"   
  8.     maxEntriesLocalDisk="1000"   
  9.     eternal="false"   
  10.     diskSpoolBufferSizeMB="20"   
  11.     timeToIdleSeconds="300"   
  12.     timeToLiveSeconds="600"   
  13.     memoryStoreEvictionPolicy="LFU"   
  14.     transactionalMode="off">  
  15.     <bootstrapCacheLoaderFactory class="com.test.encache.MyBootstrapCacheLoaderFactory"  properties="ASYNCHRONOUS=true"/>  
  16. </cache>  
  17.   
  18. <cache   
  19.     name="stateCache2"   
  20.     maxEntriesLocalHeap="10000"   
  21.     maxEntriesLocalDisk="1000"   
  22.     eternal="false"   
  23.     diskSpoolBufferSizeMB="20"   
  24.     timeToIdleSeconds="300"   
  25.     timeToLiveSeconds="600"   
  26.     memoryStoreEvictionPolicy="LFU"   
  27.     transactionalMode="off">  
  28.     <bootstrapCacheLoaderFactory class="com.test.encache.MyBootstrapCacheLoaderFactory"  properties="ASYNCHRONOUS=false"/>  
  29. </cache>  
  30.   
  31. </ehcache>  

CacheManager配置ApplicationContext.xml:

[html]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"  
  4.     xmlns:context="http://www.springframework.org/schema/context"  
  5.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"  
  6.     xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"  
  7.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  8.        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  9.        http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring  
  10.      http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd"  
  11.      default-autowire="byType">  
  12.       
  13.     <ehcache:annotation-driven cache-manager="ehCacheManager" />   
  14.   
  15.     <bean id="ehCacheManager"   
  16.         class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">   
  17.         <property name="configLocation">   
  18.             <value>src/config/myehcache.xml</value>   
  19.         </property>  
  20.     </bean>   
  21.       
  22. </beans>  

最后是测试代码:BootstrapCacheLoaderTest.java:

[java]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  *  
  3.  * Copyright (c) 2004-2014 All Rights Reserved. 
  4.  */  
  5. package com.test.encache;  
  6.   
  7. import java.io.FileInputStream;  
  8. import java.io.FileNotFoundException;  
  9. import java.io.IOException;  
  10. import java.util.Properties;  
  11.   
  12. import net.sf.ehcache.Cache;  
  13. import net.sf.ehcache.CacheManager;  
  14. import net.sf.ehcache.Element;  
  15.   
  16. import org.apache.log4j.PropertyConfigurator;  
  17. import org.slf4j.Logger;  
  18. import org.slf4j.LoggerFactory;  
  19. import org.springframework.context.ApplicationContext;  
  20. import org.springframework.context.support.FileSystemXmlApplicationContext;  
  21.   
  22. /** 
  23.  *  
  24.  * @author  
  25.  * @version $Id: BootstrapCacheLoader.java, v 0.1 2014年10月18日 上午11:31:06 Exp $ 
  26.  */  
  27. public class BootstrapCacheLoaderTest {  
  28.     private static String       log4jFileName      = "src/config/log4j.properties";  
  29.     private static String       xmlFileName        = "src/config/ApplicationContext.xml";  
  30.     private static String       ehcacheXmlFileName = "src/config/myehcache.xml";  
  31.   
  32.     private static final Logger logger             = LoggerFactory  
  33.                                                        .getLogger(BootstrapCacheLoaderTest.class);  
  34.   
  35.     private static CacheManager ehCacheManager;  
  36.   
  37.     public static void main(String[] args) {  
  38.         configProperty();  
  39.   
  40.         xmlLoad(ehcacheXmlFileName);  
  41.   
  42.         String[] cacheNamesStrings = ehCacheManager.getCacheNames();  
  43.         logger.info("the number of caches in ehCacheManager : " + cacheNamesStrings.length);  
  44.         Cache cache = ehCacheManager.getCache(CacheConstants.CACHE_NAME1);  
  45.         Element element = cache.get(CacheConstants.KEY_ARRAY[0]);  
  46.         logger.info("the element of key  " + CacheConstants.KEY_ARRAY[0] + " is " + element);  
  47.   
  48.     }  
  49.   
  50.     /** 
  51.      * config properties 
  52.      *  
  53.      */  
  54.     private static void configProperty() {  
  55.         Properties properties = new Properties();  
  56.         FileInputStream istream;  
  57.         try {  
  58.             istream = new FileInputStream(log4jFileName);  
  59.             properties.load(istream);  
  60.             istream.close();  
  61.         } catch (FileNotFoundException e) {  
  62.             logger.error("File not found", e);  
  63.         } catch (IOException e) {  
  64.             logger.error("load file erroe", e);  
  65.         } finally {  
  66.   
  67.         }  
  68.   
  69.         //properties.setProperty("log4j.appender.file.File",logFile);   
  70.         PropertyConfigurator.configure(properties);  
  71.         logger.info("config properties success.");  
  72.     }  
  73.   
  74.     private static void xmlLoad(String fileName) {  
  75.         ApplicationContext ctx = new FileSystemXmlApplicationContext(xmlFileName);  
  76.   
  77.         ehCacheManager = (CacheManager) ctx.getBean("ehCacheManager");  
  78.   
  79.     }  
  80. }  


输出结果:
2014-10-18 15:17:45 INFO  BootstrapCacheLoaderTest:71 - config properties success.
2014-10-18 15:17:45 INFO  FileSystemXmlApplicationContext:513 - Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@687b6889: startup date [Sat Oct 18 15:17:45 CST 2014]; root of context hierarchy
2014-10-18 15:17:45 INFO  XmlBeanDefinitionReader:316 - Loading XML bean definitions from file [D:\code\test\encache\src\config\ApplicationContext.xml]
2014-10-18 15:17:45 INFO  EhCacheManagerFactoryBean:136 - Initializing EhCache CacheManager
2014-10-18 15:17:46 INFO  MyBootstrapCacheLoaderFactory:38 - MyBootstrapCacheLoaderFactory : create a BootstrapCacheLoader
2014-10-18 15:17:46 INFO  MyBootstrapCacheLoaderFactory:38 - MyBootstrapCacheLoaderFactory : create a BootstrapCacheLoader
2014-10-18 15:17:46 INFO  MyBootstrapCacheLoaderFactory:34 - load your cache with whatever you want....
2014-10-18 15:17:46 INFO  MyBootstrapCacheLoaderFactory:51 - load end....
2014-10-18 15:17:46 INFO  MyBootstrapCacheLoaderFactory:34 - load your cache with whatever you want....
2014-10-18 15:17:46 INFO  MyBootstrapCacheLoaderFactory:51 - load end....
2014-10-18 15:17:46 INFO  BootstrapCacheLoaderTest:43 - the number of caches in ehCacheManager : 2
2014-10-18 15:17:46 INFO  BootstrapCacheLoaderTest:46 - the element of key  KEY1 is [ key = KEY1, value=value1, version=1, hitCount=1, CreationTime = 1413616666238, LastAccessTime = 1413616666302 ]


参考资料

Ehcache关于预热机制的官方文档

Load EhCache diskstore content into memory

How to load data to Ehcache when the application starts

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ehcache3 中,要配置持久缓存需要进行如下配置: 1. 首先,在 cache-template xml 中定义一个 persistence,用于指定缓存数据的持久化存储位置。例如: ``` <persistence directory="path/to/disk/store" /> ``` 2. 然后,在 cache-template xml 中为需要进行持久化缓存缓存区域添加一个 cache 标签,并在其中指定 persistence 属性为 true,表示启用持久化功能。例如: ``` <cache alias="myCache"> <key-type>java.lang.String</key-type> <value-type>java.lang.String</value-type> <resources> <heap unit="entries">10000</heap> <disk unit="entries">10000000</disk> </resources> <persistence strategy="LOCALTEMPSWAP" /> </cache> ``` 3. 最后,在 cache-template xml 中将需要进行持久化缓存缓存区域和之前定义的 persistence 关联起来。例如: ``` <config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://www.ehcache.org/v3' xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.8.xsd"> <cache-template name="myCacheTemplate"> <cache alias="myCache"> <key-type>java.lang.String</key-type> <value-type>java.lang.String</value-type> <resources> <heap unit="entries">10000</heap> <disk unit="entries">10000000</disk> </resources> <persistence strategy="LOCALTEMPSWAP" /> </cache> <persistence directory="path/to/disk/store" /> </cache-template> </config> ``` 这样配置之后,缓存数据可以在应用重启后仍然存在于指定的持久化存储位置中。需要注意的是,持久化缓存会对性能产生一定的影响,因此需要根据实际情况进行综合考虑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值