少年阿賓

          那些青春的歲月

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks
          Cache簡介: 緩存(Cache )是計算機領域非常通用的概念。它介于應用程序和永久性數據存儲源(如硬盤上的文件或者數據庫)之間,其作用是降低應用程序直接讀寫永久性數據存儲源的頻率,從而提高應用的運行性能。緩存中的數據是數據存儲源中數據的拷貝,應用程序在運行時直接讀寫緩存中的數據,只在某些特定時刻按照緩存中的數據來同步更新數據存儲源。
          緩存的物理介質通常是內存,而永久性數據存儲源的物理介質通常是硬盤或磁盤,應用程序讀寫內在的速度顯然比讀寫硬盤的速度快,如果緩存中存放的數據量非常大,也會用硬盤作為緩存的物理介質。
          緩存的實現不僅需要作為物理介質的硬件,同時還需要用于管理緩存的并發訪問和過期等策略的軟件。因此,緩存是通過軟件和硬件共同實現的。
          1.1.    持久化層的緩存的范圍
          緩存的范圍決定了緩存的生命周期以及可以被誰訪問。緩存的范圍分為三類。
          1) 事務范圍:緩存只能被當前事務訪問。緩存的生命周期依賴于事務的生命周期,當事務結束時,緩存也就結束生命周期。在此范圍下,緩存的介質是內存。事務可以是數據庫事務或者應用事務,每個事務都有獨自的緩存,緩存內的數據通常采用相互關聯的對象形式。
          2) 進程范圍:緩存被進程內的所有事務共享。這些事務有可能是并發訪問緩存,因此必須對緩存采取必要的事務隔離機制。緩存的生命周期依賴于進程的生命周期,進程結束時,緩存也就結束了生命周期。進程范圍的緩存可能會存放大量的數據,所以存放的介質可以是內存或硬盤。緩存內的數據既可以是相互關聯的對象形式也可以是對象的松散數據形式。松散的對象數據形式有點類似于對象的序列化數據,但是對象分解為松散的算法比對象序列化的算法要求更快。
          3) 集群范圍:在集群環境中,緩存被一個機器或者多個機器的進程共享。緩存中的數據被復制到集群環境中的每個進程節點,進程間通過遠程通信來保證緩存中的數據的一致性,緩存中的數據通常采用對象的松散數據形式。
          對大多數應用來說,應該慎重地考慮是否需要使用集群范圍的緩存,因為訪問的速度不一定會比直接訪問數據庫數據的速度快多少。
          持久化層可以提供多種范圍的緩存。如果在事務范圍的緩存中沒有查到相應的數據,還可以到進程范圍或集群范圍的緩存內查詢,如果還是沒有查到,那么只有到數據庫中查詢。事務范圍的緩存是持久化層的第一級緩存,通常它是必需的;進程范圍或集群范圍的緩存是持久化層的第二級緩存,通常是可選的。
          1.2.    持久化層的緩存的并發訪問策略
          當多個并發的事務同時訪問持久化層的緩存的相同數據時,會引起并發問題,必須采用必要的事務隔離措施。
          在進程范圍或集群范圍的緩存,即第二級緩存,會出現并發問題。因此可以設定以下四種類型的并發訪問策略,每一種策略對應一種事務隔離級別。
          1) 事務型(Transactional)策略:僅僅在受管理環境中適用。它提供了Repeatable Read事務隔離級別。對于經常被讀但很少修改的數據,可以采用這種隔離類型,因為它可以防止臟讀和不可重復讀這類的并發問題。
          2) 讀寫型(read-write)策略:提供了Read Committed事務隔離級別。僅僅在非集群的環境中適用。對于經常被讀但很少修改的數據,可以采用這種隔離類型,因為它可以防止臟讀這類的并發問題。
          3) 非嚴格讀寫型(nonstrict-read-write)策略:不保證緩存與數據庫中數據的一致性。如果存在兩個事務同時訪問緩存中相同數據的可能,必須為該數據配置一個很短的數據過期時間,從而盡量避免臟讀。對于極少被修改,并且允許偶爾臟讀的數據,可以采用這種并發訪問策略。
          4) 只讀型策略(read-only):對于從來不會修改的數據,如參考數據,可以使用這種并發訪問策略。
          事務型并發訪問策略是事務隔離級別最高,只讀型的隔離級別最低。事務隔離級別越高,并發性能就越低。
          2.    Hibernate中的緩存:
          Hibernate中提供了兩級Cache,第一級別的緩存是Session級別的緩存,它是屬于事務范圍的緩存。這一級別的緩存由hibernate管理的,一般情況下無需進行干預;第二級別的緩存是SessionFactory級別的緩存,它是屬于進程范圍或群集范圍的緩存。這一級別的緩存可以進行配置和更改,并且可以動態加載和卸載。
          Hibernate還為查詢結果提供了一個查詢緩存,它依賴于第二級緩存。
          2.1.    一級緩存和二級緩存的比較:

          第一級緩存
          第二級緩存
          存放數據的形式
          相互關聯的持久化對象
          對象的散裝數據
          緩存的范圍
          事務范圍,每個事務都有單獨的第一級緩存
          進程范圍或集群范圍,緩存被同一個進程或集群范圍內的所有事務共享
          并發訪問策略
          由于每個事務都擁有單獨的第一級緩存,不會出現并發問題,無需提供并發訪問策略
          由于多個事務會同時訪問第二級緩存中相同數據,因此必須提供適當的并發訪問策略,來保證特定的事務隔離級別
          數據過期策略
          沒有提供數據過期策略。處于一級緩存中的對象永遠不會過期,除非應用程序顯式清空緩存或者清除特定的對象
          必須提供數據過期策略,如基于內存的緩存中的對象的最大數目,允許對象處于緩存中的最長時間,以及允許對象處于緩存中的最長空閑時間
          物理存儲介質
          內存
          內存和硬盤。對象的散裝數據首先存放在基于內在的緩存中,當內存中對象的數目達到數據過期策略中指定上限時,就會把其余的對象寫入基于硬盤的緩存中。
          緩存的軟件實現
          在Hibernate的Session的實現中包含了緩存的實現
          由第三方提供,Hibernate僅提供了緩存適配器(CacheProvider)。用于把特定的緩存插件集成到Hibernate中。
          啟用緩存的方式
          只要應用程序通過Session接口來執行保存、更新、刪除、加載和查詢數據庫數據的操作,Hibernate就會啟用第一級緩存,把數據庫中的數據以對象的形式拷貝到緩存中,對于批量更新和批量刪除操作,如果不希望啟用第一級緩存,可以繞過Hibernate API,直接通過JDBC API來執行指操作。
          用戶可以在單個類或類的單個集合的粒度上配置第二級緩存。如果類的實例被經常讀但很少被修改,就可以考慮使用第二級緩存。只有為某個類或集合配置了第二級緩存,Hibernate在運行時才會把它的實例加入到第二級緩存中。
          用戶管理緩存的方式
          第一級緩存的物理介質為內存,由于內存容量有限,必須通過恰當的檢索策略和檢索方式來限制加載對象的數目。Session的evit()方法可以顯式清空緩存中特定對象,但這種方法不值得推薦。
          第二級緩存的物理介質可以是內存和硬盤,因此第二級緩存可以存放大量的數據,數據過期策略的maxElementsInMemory屬性值可以控制內存中的對象數目。管理第二級緩存主要包括兩個方面:選擇需要使用第二級緩存的持久類,設置合適的并發訪問策略:選擇緩存適配器,設置合適的數據過期策略。
          2.2.    一級緩存的管理:
          當應用程序調用Session的save()、update()、savaeOrUpdate()、get()或load(),以及調用查詢接口的list()、iterate()或filter()方法時,如果在Session緩存中還不存在相應的對象,Hibernate就會把該對象加入到第一級緩存中。當清理緩存時,Hibernate會根據緩存中對象的狀態變化來同步更新數據庫。
          Session為應用程序提供了兩個管理緩存的方法:
          evict(Object obj):從緩存中清除參數指定的持久化對象。
          clear():清空緩存中所有持久化對象。
          2.3.    二級緩存的管理:
          2.3.1.      Hibernate的二級緩存策略的一般過程如下:
          1) 條件查詢的時候,總是發出一條select * from table_name where …. (選擇所有字段)這樣的SQL語句查詢數據庫,一次獲得所有的數據對象。 
          2) 把獲得的所有數據對象根據ID放入到第二級緩存中。 
          3) 當Hibernate根據ID訪問數據對象的時候,首先從Session一級緩存中查;查不到,如果配置了二級緩存,那么從二級緩存中查;查不到,再查詢數據庫,把結果按照ID放入到緩存。 
          4) 刪除、更新、增加數據的時候,同時更新緩存。
            Hibernate的二級緩存策略,是針對于ID查詢的緩存策略,對于條件查詢則毫無作用。為此,Hibernate提供了針對條件查詢的Query Cache。
          2.3.2.      什么樣的數據適合存放到第二級緩存中?
          1 很少被修改的數據
          2 不是很重要的數據,允許出現偶爾并發的數據
          3 不會被并發訪問的數據
          4 參考數據,指的是供應用參考的常量數據,它的實例數目有限,它的實例會被許多其他類的實例引用,實例極少或者從來不會被修改。
          2.3.3.      不適合存放到第二級緩存的數據?
          1 經常被修改的數據
          2 財務數據,絕對不允許出現并發
          3 與其他應用共享的數據。
          2.3.4.      常用的緩存插件
          Hibernater 的二級緩存是一個插件,下面是幾種常用的緩存插件:
          l EhCache:可作為進程范圍的緩存,存放數據的物理介質可以是內存或硬盤,對Hibernate的查詢緩存提供了支持。
          l OSCache:可作為進程范圍的緩存,存放數據的物理介質可以是內存或硬盤,提供了豐富的緩存數據過期策略,對Hibernate的查詢緩存提供了支持。
          l SwarmCache:可作為群集范圍內的緩存,但不支持Hibernate的查詢緩存。
          l JBossCache:可作為群集范圍內的緩存,支持事務型并發訪問策略,對Hibernate的查詢緩存提供了支持。
          2.3.5.      配置二級緩存的主要步驟:
          1)      選擇需要使用二級緩存的持久化類,設置它的命名緩存的并發訪問策略。這是最值得認真考慮的步驟。
          2)      選擇合適的緩存插件,然后編輯該插件的配置文件。
           
           
          1.  首先設置EhCache,建立配置文件ehcache.xml,默認的位置在class-path,可以放到你的src目錄下:
          <ehcache>
              <diskStore path="c:\\ehcache\"/> 
              <defaultCache 
                  maxElementsInMemory="10000" 
                  eternal="false" 
                  timeToIdleSeconds="120" 
                  timeToLiveSeconds="120" 
                  overflowToDisk="true"   
                  />
                  
              <!-- 設置Category類的緩存的數據過期策略 -->
              <cache name="org.qiujy.domain.cachedemo.Category"
                  maxElementsInMemory="100"
                  eternal="true"
                  timeToIdleSeconds="0"
                  timeToLiveSeconds="0"
                  overflowToDisk="false"
                  />
                  
               <!-- 設置Category類的products集合的緩存的數據過期策略 -->
               <cache name="org.qiujy.domain.cachedemo.Category.products"
                  maxElementsInMemory="500"
                  eternal="false"
                  timeToIdleSeconds="300"
                  timeToLiveSeconds="600"
                  overflowToDisk="true"
                  />
                  
              <cache name="org.qiujy.domain.cachedemo.Product"
                  maxElementsInMemory="500"
                  eternal="false"
                  timeToIdleSeconds="300"
                  timeToLiveSeconds="600"
                  overflowToDisk="true"
                  />    
          </ehcache>
          配置的元素說明:
          元素或屬性
          描述
          <diskStore>
          設置緩存數據文件的存放目錄
          <defaultCache>
          設置緩存的默認數據過期策略
          <cache>
          設定具體的命名緩存的數據過期策略
          每個命名緩存代表一個緩存區域,每個緩存區域有各自的數據過期策略。命名緩存機制使得用戶能夠在每個類以及類的每
            2.  在Hibernate配置文件中設置:

          <hibernate-configuration>
          <session-factory>……<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property><property name="cache.use_second_level_cache">true</property>……</session-factory></hibernate-configuration>        此外,可以把cache.use_second_level_cache設置為false關閉所有的hibernate二級緩存。但此屬性對指定<cache>的類缺省為true。
           
             3.  為了使用二級緩存,需要在每一個Hibernate Entity上配置。
          @Entity   
          @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)    
          public class Forest { ... }   
          @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)    
          @JoinColumn(name="CUST_ID")    
          @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)    
          public SortedSet getTickets() {    
              return tickets;    
          }   
          @Cache(    
              CacheConcurrencyStrategy usage();                 (1)    
              String region() default "";                       (2)    
              String include() default "all";                   (3)    
          )   
          (1) usage: 提供緩存對象的事務隔離機制,可選值有以下幾種
          (NONE, READ_ONLY, NONSTRICT_READ_WRITE(非嚴格讀寫), READ_WRITE, TRANSACTIONAL)
          (2) region (optional): 指定緩存的區域,默認是類的全限定名。利用緩存區域,可以更精確的指定每個區域的緩存超前策略。如果指定了緩存區域前綴(在hibernate.cfg.xml中設置cache.region_prefix屬性為一個字符串),則所有的緩存區域名前將加上這個前綴。
          (3) include (optional): all to include all properties, non-lazy to only include non lazy properties (default all).
          如果不是使用annotation的話,則是在Hbm文件中添加cache usage="read-only"



          http://blog.163.com/seara520@126/blog/static/7206930420102232340810/
          posted on 2012-05-14 09:24 abin 閱讀(1116) 評論(0)  編輯  收藏 所屬分類: cache

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 成都市| 江城| 新和县| 宣恩县| 长武县| 彭山县| 清丰县| 衢州市| 翼城县| 沅陵县| 常州市| 黄冈市| 秦安县| 上虞市| 濮阳市| 鄢陵县| 东山县| 开化县| 乌审旗| 商都县| 醴陵市| 防城港市| 英超| 台南县| 荔波县| 潜江市| 扬中市| 盐山县| 华宁县| 黄山市| 应用必备| 庆城县| 夏邑县| 宜兰县| 武城县| 温宿县| 阿鲁科尔沁旗| 昌邑市| 上林县| 乌鲁木齐市| 玉山县|