2015年12月15日 星期二

EhCache簡介

二級cache
  1. EhCache是一個快速的、輕量級的、易於使用的、process的cache。它支持read-only和read/write cache,memory和disk cache。但是不支持Clustering。
  2. OSCache是另外一個開源的cache方案。它同時還支持JSP頁面或任意對象的cache。OSCache功能強大、靈活,和EHCache一樣支持read-only和read/write cache、支持memory和disk cache。同時,它還提供通過JGroups或JMS進行cluster的基本支持。
  3. SwarmCache 是一個簡單的、基於JavaGroups提供cluster的cache方案。支持read-only和nonstrict read/write cache。這種cache適用於讀操作遠遠高於寫操作頻率的應用。
  4. JBoss TreeCache 是一個強大的、可複製(同步或異步)和支持事務的cache。如果你需要一個真正的支持事務的cache架構,使用這個方案吧。


EHCache的使用場合
  1. 比較少更新table data,EhCache一般要使用在比較少執行write操作的table(包括update,insert,delete等)[Hibernate的二級cache也都是這樣];
Ehcache的類層次模型
主要為三層,最上層的是CacheManager,他是操作Ehcache的入口。我們可以通過CacheManager.getInstance()獲得一個單子的CacheManger,或者通過CacheManger的構造函數創建 一個新的CacheManger。每個CacheManager都管理著多個Cache。而每個Cache都以一種類Hash的方式,關聯著多個Element。Element則是我們用於存放要cache內容的地方。



Hibernate的二級cache策略的一般過程如下

  1.  條件查詢的時候,總是送出一次select * from table_name where .... (選擇所有字段樣的SQL語句查詢database,一次獲得所有的data object。
  2.  把獲得的所有data object根據ID放入到第二級cache中。
  3.  當Hibernate根據ID訪問data object的時候,首先從Session一級cache中查;查不到,如果配置了二級cache,那麼從二級cache中查;查不到,再查詢database,把結果按照ID放入到cache。
  4.  刪除、更新、增加數據的時候,同時更新cache。Hibernate的二級cache策略,是針對於ID查詢的cache策略,對於條件查詢則毫無作用。為此,Hibernate提供了針對條件查詢的Query Cache。

沒有分佈式cache需求的配置:

1. 先下載ehcache的jar包。

   解壓後,有幾個文件:

   ehcache jar:需要將它放置到WEB-INF/lib下。

   ehcache remote-debugger jar:不要deploy war中,是用來調試和監控你的cache狀況。

   ehcache.xml :重要的配置文件,需要複製到classpath下 。

2. ehcach.xml配置文件主要參數的解釋,其實文件裡有詳細的英文註釋//DiskStore 配置,cache文件的存放目錄 ,主要的value有
   * user.home - 用戶主目錄
   * user.dir - 用戶當前的工作目錄
   * java.io.tmpdir - Default temp file path默認的temp文件目錄

範例
1、首先設置EhCache,建立配置文件ehcache.XML,默認的位置在class-path,可以放到你的src目錄下:  
<?xml version="1.0" encoding="UTF-8"?> 
<ehcache> 
 <diskStore path="Java.io.tmpdir"/> 
  <defaultCache 
   maxElementsInMemory="10000" <!- cache最大數目 -> 
   eternal="false" <!- cache是否持久 -> 
   overflowToDisk="true" <!- 是否保存到disk, 當系統當機時-> 
   timeToIdleSeconds="300" <!- 當cache閒置n秒後destory -> 
   timeToLiveSeconds="180" <!- 當cache存活n秒後destory -> 
   diskPersistent="false" 
   diskExpiryThreadIntervalSeconds= "120"/> 
</ehcache> 
2、在Hibernate配置文件中設置: 
<!-- 設置Hibernate的cache implement class,這個class在Hibernate jar 中 --> 
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> 
 <!-- 是否使用query cache --> 
 <property name="hibernate.cache.use_query_cache">true</property> 
說明一下:如果不設置"query cache",那麼hibernate只會cache使用load()方法獲得的單個持久化對象,如果想cache使用findall()、list()、Iterator()、createCriteria()、createQuery()等方法獲得的數據結果集的話,就需要設置hibernate.cache.use_query_cache true才行。 
3、在Hbm.xml文件中在其<set></set>中添加<cache usage="read-only"/> 
4、如果需要"query cache",還需要在使用Query或Criteria()時設置其setCacheable(true);屬性
5、創建DAO,內容如下:
        Session s = HibernateSessionFactory.getSession(); 
        Criteria c = s.createCriteria(Xyz.class); 
        c.setCacheable(true);//這句必須要有 
        System.out.println("第一次讀取"); 
        List l = c.list(); 
        System.out.println(l.size()); 
        HibernateSessionFactory.closeSession(); 

        s = HibernateSessionFactory.getSession(); 
        c = s.createCriteria(Xyz.class); 
        c.setCacheable(true);//這句必須要有 
        System.out.println("第二次讀取"); 
        l = c.list(); 
        System.out.println(l.size()); 
        HibernateSessionFactory.closeSession();  
6、這時你會看到顯示出來的訊息為(表示第二次並沒有去讀database): 
        第一次讀取 
        Hibernate: ***** 
        13 
        第二次讀取 
        13 

首頁的頁面cache
一個網站的首頁估計是被訪問的次數最多的,我們可以考慮給首頁做一個頁面cache策略:我認為應該是某個固定時間之內不變的,比如說2分鐘更新一次,以應用結構page-filter-action-service-dao-db為例。 
        位置:頁面cache做到儘量靠近客戶的地方,就是在page和filter之間 ,這樣的優點就是第一個用戶請求之後,頁面被cache,第二個用戶再來請求的時候,走到filter這個請求就結束了,無需再走後面的action-service-dao-db。帶來的好處是server壓力的減低和client site response 速度的加快。 
<cache name="SimplePageCachingFilter" 
             maxElementsInMemory="10" 
             maxElementsOnDisk="10" 
             eternal="false" 
             overflowToDisk="true" 
             diskSpoolBufferSizeMB="20" 
             timeToIdleSeconds="10" 
             timeToLiveSeconds="10"
             memoryStoreEvictionPolicy="LFU" 
              /> 

SimplePageCachingFilter的配置
<filter> 
    <filter-name>indexCacheFilterfilter-name> 
    <filter-class> 
          net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter 
    </filter-class> 
</filter>   
<filter-mapping> 
    <filter-name>indexCacheFilter<filter-name> 
    <url-pattern>*index.action<url-pattern> 
</filter-mapping> 
就只需要這麼多步驟,我們就可以給某個頁面做一個cache,把上面這段配置放到你的web.xml中,那麼當你打開首頁的時候,你會發現,2分鐘才會有一堆sql語句出現在console上。 

cachefilter中還有一個特性,就是gzip,也就是說cache中的元素是被壓縮過的,如果客戶瀏覽器support gzip的話,filter會直接返回壓縮過的stream,這樣節省了頻寬,把解壓的工作交給了客戶瀏覽器,如果客戶的瀏覽器不支持gzip,那麼filter會把cache的元素拿出來解壓後再返回給客戶瀏覽器(大多數爬蟲是不支持gzip的,所以filter也會解壓後再返回stream),這樣做的優點是節省頻寬,缺點就是增加了客戶瀏覽器的負擔

 Ehcache的三種清空策略                                                     
1 FIFO,first in first out,這個是大家最熟的,先進先出。 
2 LFU, Less Frequently Used,就是上面例子中使用的策略,直白一點就是講一直以來最少被使用的。如上面所講,cache的元素有一個hit屬性,hit值最小的將會被清出cache。 
3 LRU,Least Recently Used,最近最少使用的,cache的元素有一個時間戳,當cache容量滿了,而又需要空出地方來cache新的元素的時候,那麼現有cache元素中時間戳離當前時間最遠的元素將被清出cache。

參考來源

沒有留言:

張貼留言