1. 程式人生 > >hibernate快取技術詳解

hibernate快取技術詳解

Cache就是快取,它往往是提高系統性能的最重要手段,對資料起到一個蓄水池和緩衝的作用。Cache對於大量依賴資料讀取操作的系統而言尤其重要。在大併發量的情況下,如果每次程式都需要向資料庫直接做查詢操作,它們所帶來的效能開銷顯而易見,頻繁的網路傳輸、資料庫磁碟的讀寫操作都會大大降低系統的整體效能。此時,如果能把資料在本地記憶體中保留一個映象,下次訪問時只需從記憶體中直接獲取,那麼顯然可以帶來顯著的效能提升。引入Cache機制的難點是如何保證記憶體中資料的有效性,否則髒資料的出現將會給系統帶來難以預知的嚴重後果。雖然一個設計得很好的應用程式不用Cache也可以表現出讓人接受的效能,但毫無疑問,一些對讀操作要求很高的應用程式可以通過Cache

取得更高的效能。對於應用程式,Cache通過記憶體或磁碟儲存了資料庫中當前有關資料狀態,它是一個存於當地的資料備份。Cache位於資料庫和應用程式之間,從資料庫中更新資料,並給程式提供資料。

Hibernate實現了良好的Cache機制,可以藉助Hibernate內部的Cache迅速提高系統資料讀取效能。Hibernate中的Cache可分為兩層:一級Cache和二級Cache

一級Cache

Session實現了第一級Cache,它屬於事務級資料緩衝。一旦事務結束,這個Cache也隨之失效。一個Session的生命週期對應一個數據庫事務或一個程式事務。

Session-cache保證在一個Session

中兩次請求同一個物件時,取得的物件是同一個Java例項,有時它可以避免不必要的資料衝突。另外,它還能保證另一些重要的效能。

在對一個物件迴圈引用時,不至於產生堆疊溢位。

當資料庫事務結束時,對於同一資料庫行,不會產生資料衝突,因為對於資料庫中的一行,至多有一個物件來表示它。

一個事務中可能會有很多個處理單元,在一個處理單元中做的操作都會立即被另外的處理單元得知。

不用刻意去開啟Session-cache,它總是被開啟並且不能被關閉。當使用save()、update()或saveOrUpdate()來儲存資料更改,或通過load()、find()、list()等方法來得到物件時,物件就會被加入到Session-cache。

如果要同步很大數量的物件,這是需要有效地管理Cache,可以用Session的evict()方法從一級Cache中移除物件。例如:

Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction() ; for(int i=0; i<100000 ;i++) { Student stu = new Student(); …. session.save(stu); } tx.commit(); session.close();

在儲存50 000個物件時,程式可能丟擲OutOfMemoryException異常,因為Hibernate在一級Cache快取了新加入資料庫的所有物件。要解決這個問題,首先設定JDBC批處理數量到一個合理的數值(一般是10~20)。在hibernate.properties配置檔案中設定如下:

 hibernate.jdbc.batch_size 20

或在hibernate.cfg.xml中設定如下:

<property name=”hibernate.jdbc.batch_size”> 20 </property>

然後在一定的時候提交更改並清空Session的Cache:

 Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction() ; for(int i=0; i<100000 ;i++) { Student stu = new Student(); …. session.save(stu); if(i%20==0) { //每儲存完20個Student物件後,進行以下操作 session.flush(); //提交更新 session.clear(); //清除Cache,釋放記憶體 } } tx.commit(); session.close();


二級Cache

二級Cache是SessionFactory範圍內的快取,所有的Session共享同一個二級Cache。在二級Cache中儲存永續性例項的散裝形式的資料。二級Cache的內部是如何實現的並不重要,重要的是採用哪種正確的快取策略,以及採用哪種Cache Providers。持久化不同的資料需要不同的Cache策略,比如說一些因素將影響到Cache策略選擇:資料的讀/寫比例、資料表是否能被其他的應用程式所訪問等。對於一些讀/寫比例高的資料可以開啟它的快取,允許這些資料進入二級快取容器有利於系統性能的優化;而對於能被其他應用程式訪問的資料物件,最好將此物件的二級Cache選項關閉。

設定Hibernate的二級Cache需要分兩步進行:首先確認使用什麼資料併發策略,然後配置快取過期時間和設定Cache提供器。

有4種內建的Hibernate資料併發衝突策略,代表了資料庫隔離級別,如下所示。

transactional:僅在受管理的環境中可用。它保證可重讀的實物隔離級別,可以對讀/寫比例高、很少更新的資料採用這種策略。

read-write:使用timestamp機制維護讀已提交事務隔離級別。可以對讀/寫比例高、很少更新的資料採用這策略。

nonstrict-read-write:不保證Cache和資料庫之間的資料一致性。使用此策略時,應該設定足夠短的快取過期時間,否則可能從快取中讀出髒資料。當一些資料極少改變,並且當這些資料和資料庫有一部分不一致但影響不大時,可以使用此策略。

read-only:當確保資料永不改變時,可以使用此策略。

確定了Cache策略之後,就要挑選一個合適高效的Cache提供器,它作為外掛被Hibernate呼叫。Hibernate允許使用下述幾種快取外掛。

EhCache:可以在JVM中作為一個簡單程序範圍的快取,它可以把快取的資料放入記憶體或磁碟,並支援Hibernate中可選用的查詢快取。

OpenSymphony OSCache:和EhCache相似,並且它提供了豐富的快取過期策略。 SwarmCache:可作為叢集範圍的快取,但不支援查詢快取。 JBossCache:可作為叢集範圍的快取,但不支援查詢快取。

上述4種快取外掛的對比情況列於表9-3中。 表9-3  4種快取外掛的對比情況

支援非嚴格讀寫

EhCache

OSCache

SwarmCache

JBossCache

它們的提供器列於表9-4中。 表9-4  快取策略的提供器

提供器(Cache Providers

Hashtable(只能測試時使用)

org.hibernate.cache.HashtableCacheProvider

EhCache

org.hibernate.cache.EhCacheProvider

OSCache

org.hibernate.cache.OSCacheProvider

SwarmCache

org.hibernate.cache.SwarmCacheProvider

JBossCache

org.hibernate.cache.TreeCacheProvider

在預設情況下,Hibernate使用EhCache進行JVM級別的快取。使用者可以通過設定Hibernate配置檔案中的hibernate.cache.provider_class的屬性,指定其他的快取策略,該快取策略必須實現org.hibernate.cache.CacheProvider介面。

在Hibernate中使用EhCache

EhCache是一個純Java程式,可以在Hibernate中作為一個外掛引入。它具有執行速度快、結構簡單、佔用記憶體小、很小的依賴性、支援多CPU伺服器、文件齊全等特點。

在Hibernate中使用EhCache,需要在hibernate.cfg.xml中設定如下:

<property name=” hibernate.cache.provider_class”> org.hibernate.cache.EhCacheProvider </property>

EhCacheProvider類位於hibernate3.jar包中,而不是位於ehcache-1.1.jar包中。EhCache有自己的配置文件,名為ehcache.xml。在Hibernate3.x中的etc目錄下有ehcache.xml的示範檔案,將其複製應用程式的src目錄下(編譯時會把ehcache.xml複製到WEB-INF/classess目錄下),對其中的相關值進行更改以和自己的程式相適合。進行配置後,在ehcache.xml檔案中的全部程式碼如下:

  <diskStore path="d://cache"/> //設定cache.data檔案的存放位置

    <defaultCache maxElementsInMemory="10000" //快取中允許建立的最大物件數 eternal="false" //快取中物件是否為永久的timeToIdleSeconds="120" //快取資料鈍化時間(即物件在它過期前的空閒時間) timeToLiveSeconds="120" //快取資料生存時間(即物件在它過期前的生存時間) overflowToDisk="true"  //是否啟用磁碟快取 />

    <cache name="Student"   //使用者自定義的Cache配置maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" /> </ehcache>


<diskStore>:指定一個檔案目錄,當EHCache把資料寫到硬碟上時,將把資料寫到這個檔案目錄下。

  <defaultCache>:設定快取的預設資料過期策略。

  <cache>:設定具體的命名快取的資料過期策略。

  在對映檔案中,對每個需要二級快取的類和集合都做了單獨的配置,與此對應,在ehcache.xml檔案中通過<cache>元素來為每個需要二級快取的類和集合設定快取的資料過期策略。下面解釋一下<cache>元素的各個屬性的作用:

  name:設定快取的名字,它的取值為類的完整名字或者類的集合的名字,如果name屬性為mypack.Category,表示 Category類的二級快取;如果name屬性為mypack.Category.items,表示Category類的items集合的二級快取。

  maxInMemory:設定基於記憶體的快取可存放的物件的最大數目。

  eternal:如果為true,表示物件永遠不會過期,此時會忽略timeToIdleSeconds和timeToLiveSeconds屬性。預設為false。

  timeToIdleSeconds:設定允許物件處於空閒狀態的最長時間,以秒為單位,當物件從最近一次被訪問後,如果處於空閒狀態的時間超過了指定的值,這個物件會過期,EHCache將把它從快取中清除,只有當eternal屬性為false,它才有效,值為0表示物件可以無限期地處於空閒狀態。

  timeToLiveSeconds:設定物件允許存在於快取中的最長時間,以秒為單位,當物件自從被放入快取中後,如果處於快取中的時間超過了指定的值,這個物件就會過期,EHCache將把它從快取中清除,只有當eternal屬性為false,它才有效,值為0表示物件可以無限期地處於空閒狀態。它的值必須大於或等於timeToIdleSeconds的值才有意義。

  overflowToDisk:如果為true,表示當基於記憶體的快取中的物件數目達到了maxInMemory界限,會把溢位的物件寫到基於硬碟的快取中。


此外,還需要在持久化類的對映檔案中進行配置。例如,Group(班級)和Student(學生)是一對多的關係,它們對應的資料表分別是t_group和t_student。現在要把Student類的資料進行二級快取,這需要在兩個對映檔案(Student.hbm.xml和Group.hbm.xml)中都對二級快取進行配置。

在Group.hbm.xml中配置二級快取如下:

    …… <hibernate-mapping> <class name="Group" table="t_group" lazy="false"> …… <set name="students" cascade="save-update" inverse="true"   <!--關係由Student維護--> lazy="true" > <cache usage="read-write"/>  //<!--集合中的資料將被快取--> <key column="id"/> <one-to-many class="Student"/> </set></class> </hibernate-mapping> ……

上述檔案雖然在<set>標記中設定了<cache usage="read-write"/>,但Hibernate僅把和Group相關的Student的主鍵id加入到快取中,如果希望把整個Student的散裝屬性都加入到二級快取中,還需要在Student.hbm.xml檔案的<class>標記中加入<cache>子標記,如下所示:

<class name="Student" table="t_student" > <cache usage="read-write" /> <!--cache標記需跟在class標記後--> …… </class>



增加點知識

    測試二級快取:現在仍用前面的類來測試,儘管第一個session關閉了,但是我們在第二個session查詢時,仍不會連庫,這也就是二級快取的作用,通常情況下,hibernate查詢時會首先在一級快取中查詢資料,再到二級快取中查詢,如果仍查不到才會連庫。 這時請注意,儘管我們在一級快取中清掉了資料,但是在二級快取中還存有資料,所以在清掉資料後執行的查詢操作也不會引起連庫,這就是為什麼我們最終只看到一條查詢語句的原因。強調,前面說用evict或clear只是清掉一級快取中的內容。

感知二級快取:經過上面的測試我們不能明確感知到二級快取的作用效果,下面我們配置“統計資訊”屬性來進行二級快取資訊的獲取。首先我們在主配置檔案中配置以下屬性:<propertyname="hibernate.generate_statistics">true</property>來開啟統計資訊,由於統計資訊會耗資源,所以一般不開啟。然後在測試類的main方法中增加如下程式碼:     

       Statistics st = HibernateUtil.getSessionFactory().getStatistics();

       System.out.println(st);

       System.out.println("put:" + st.getSecondLevelCachePutCount());

       System.out.println("hit:" + st.getSecondLevelCacheHitCount());

       System.out.println("miss:" + st.getSecondLevelCacheMissCount());

執行後結果為:

put:1

hit:2

miss:1    在進行程式碼結果分析前先來說兩個概念:命中,miss命中是指在二級快取中查到資料,沒有找到就稱為miss.  命中率:在查詢時有多少次是從快取中得到。 下面我們看上面的執行結果put=1,說明hibernate放了一次資料到快取中,這發生在第一次查詢時,當不能在二級快取中找到(這也是為什麼會有一次miss的原因)時,會去連庫並把資料放到快取中去,使put變為1.隨後進行的三次查詢中:第一次仍是從一級快取中查詢到,後兩次查詢均在二級快取中查到,所以命中hit=2。

4.二級快取中的細節問題:

(1)體會save自動填充快取,save填充快取不支援id的native方式生成,所以我們先修改User的實體配置檔案讓id生成方式為:

Java程式碼  收藏程式碼
  1. <id name="id">  
  2.             <generator class="hilo"/>  
  3. </id>  

後,這樣修改後再來測試執行結果會發現執行結果為:

put:1

hit:3

miss:0  

分析:當我們儲存User物件到資料庫時也會自動把此資料填充到快取中,所以第一次put實質是發生在儲存資料時。這樣也就不難解釋為什麼hit=3,miss=0了。

(2)除了save外,update、saveOrUpdate、list、iterator、get、load(查詢時從二級快取中取資料的三個方法)、Query、Criteria都會填充二級快取,且它們支援主鍵的nativa生成方式。

(3)讓Query支援二級快取:首先是主配置中配置如下屬性:

<property name="#hibernate.cache.use_query_cache">true</property>因為Query命中率較低,所以預設此屬性是關閉的。隨後在Query方式查詢時設定q.setCacheable(true);這兩步執行後便完成了讓Query支援二級快取。

(4)怎樣清除二級快取:HibernateUtil.getSessionFactory().evict(User.class);這樣將清除二級快取中所有的User類相關的資料。


分步式快取:

首先我們用圖來模擬分步式快取


說明:在大型的web系統中,通常都會採用多個伺服器來進行web服務,比如在上面的例項中,我們在伺服器一存有“資料data,在伺服器二中也存有這個資料,但當我們在伺服器N中更改這個資料時,如果我們繼續訪問在伺服器一或二的資料,將不能得到正確的資料,這時採取的方式就是隻要有伺服器改變這個資料就在這些伺服器組成的內網中廣播這個資訊來更新每個改變的資料。雖然伺服器在內網中通訊,但是這種方式也是非常耗資源的,後來提出了“中央快取”來解決此問題,如下圖:

原理:當我們去某個伺服器查詢資料時,這個伺服器會去中央快取查詢,同樣如果下面的某個伺服器修改資料時,中央快取也會及時把資料更新到庫並重新儲存新資料。但是如果資料互動快的話,我們仍不能保證資料這些伺服器訪問中央快取時是及時資料。比如在伺服器一訪問中央快取修改資料時,其它的幾個伺服器也能訪問修改,這樣就不能保證及時獲取正確資訊。所以使用快取的條件有如下幾點:讀取大於寫入;資料量不能超過記憶體容量;對資料要有獨立的控制;允許無效的資料存在。

相關推薦

hibernate快取技術

Cache就是快取,它往往是提高系統性能的最重要手段,對資料起到一個蓄水池和緩衝的作用。Cache對於大量依賴資料讀取操作的系統而言尤其重要。在大併發量的情況下,如果每次程式都需要向資料庫直接做查詢操作,它們所帶來的效能開銷顯而易見,頻繁的網路傳輸、資料庫磁碟的讀寫操作都會

Hibernate框架中的快取技術

Hibernate框架的快取分為Session的快取、SessionFactory的快取,也稱為一級快取和二級快取。 一級快取: 一級快取是Session級的快取,其生命週期很短,與Session相互對應,由Hibernate進行管理,屬於事務範圍的快取。當程式呼叫 Session的load

CDN快取伺服器負載均衡叢集《CDN技術

1. 集群系統 1.1 集群系統分類 伺服器叢集的分類,可以分為三種分別是計算叢集、負載均衡叢集、高可用叢集,下面分析對計算叢集、負載均衡叢集和高可用叢集做以詳細講解。 根據用途的不同,我們把伺服器叢集分為如下幾類。 (1)計算叢集 伺服器計算叢集通常被用於承載

Hibernate中一二級快取使用

一、一級快取二級快取的概念解釋 (1)一級快取就是Session級別的快取,一個Session做了一個查詢操作,它會把這個操作的結果放在一級快取中,如果短時間內這個session(一定要同一個session)又做了同一個操作,那麼hibernate直接從一級快取中拿,而

實現高性能糾刪碼引擎 | 糾刪碼技術(下)

糾刪碼引擎 基礎知識 深入優化 技術 工程師 作者介紹: 徐祥曦,七牛雲工程師,獨立開發了多套高性能糾刪碼/再生碼編碼引擎。柳青,華中科技大學博士,研究方向為基於糾刪碼的分布式存儲系統。前言:在上篇《如何選擇糾刪碼編碼引擎》中,我們簡單了解了 Reed-Solomon Codes(RS 碼

Nginx技術(2)

web服務器 nginx部署一個Web站點:服務器準備:node0IP:192.168.10.3進入/application/nginx/html/下把index.html文件刪除:rm -rf /application/nginx/html/index.html創建index.html文件,並追加文本:ec

Nginx技術(1)

web服務器 nginxNginx Web服務應用:Nginx(engine x)是一個開源的,支持高並發的www服務和代理服務軟件。Nginx是俄羅斯人Igor Sysoev開發的,最初被應用到俄羅斯的大型網站(www.rambler.ru)上。後來作者將源代碼以類BSD許可證的形式開源出來供全球使用。在功

JSP/Servlet及相關技術

script return 指令 o-c rip title info turn expires JSP聲明 <%!聲明部分%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitio

C#漢字轉換拼音技術(高性能)

rim none pie 存在 asp pub net 如果 pinyin public static class ChineseToPinYin { private static readonly Dictionary<<span class=

14.javaweb AJAX技術

填充 cut pub cti div htm .get conn lec 一、簡介 1, ajax:在不重新加載網頁的前提下,與服務器交換數據並更新部分網頁的技巧,但其本身並不是一種新技術 2, 核心:XMLHttpRequest對象。AJAX技術主要是通過此

掃地機器人的構造及核心技術

智能掃地機器人  掃地機器人,又稱自動打掃機、智能吸塵、機器人吸塵器等,是智能家居電器的一種,能憑借一定的人工智能,自動在房間內完成地板清理工作。一般采用刷掃和真空方式,將地面雜物先吸納進入自身的垃圾收納盒,從而完成地面清理的功能。一般來說,將完成清掃、吸塵、擦地工作的機器人,也統一歸為掃地機器人。  掃地機

CDN技術(七)

事務 失敗 需求 重復數 ebsp 一個 解析 設置 不用 動態內容加速服務的實現 隨著Web2.0的興起,產生了動態網頁、個性化內容、電子交易數據等內容的加速,這些就涉及了動態內容加速技術。 靜態內容的加速,都是對於表現層的加速,對於動態頁面等內容的加速,則要涉及邏輯層

《Unity3D 實戰核心技術》書中關於矩陣的錯誤

不同的 linear 應該 印刷 幫助 tar 線性代數 計算 計算機圖形學 最近一直在學習實時渲染,不免要接觸線性代數。而渲染中,一定會用到矩陣,當我再次去復習我之前看的書時,發現《Unity3D 實戰核心技術詳解》關於矩陣就有幾處錯誤 ,特標註出來。 書的第一章《3

HTTP協議報文、工作原理及Java中的HTTP通信技術

tor 報文 buffered mod protoc 禁止 ans 請求報文 客戶端 博客園 首頁 新隨筆 聯系 管理 訂閱

ajax技術,封裝一個原生的ajax請求

status 語法 match 基礎上 abort param sync 可選參數 導致 一、Ajax 概述 Ajax 是 Asynchronous Javascript And XML 的簡寫 Ajax是一門技術,並不是一門語言 使用XHTML+CSS來標準化呈現 使

mysql主從復制技術

mysql主從復制技術詳解M-S主服務器:master1第一步:打開bin-log日誌,設置如下:vim /etc/my.cnflog_binserver-id=1gtid_mode=ONenforce_gtid_consistency=1第二步:進入數據庫授權用戶mysql -uroot -p‘密碼‘gra

Hibernate學習(2)- hibernate.cfg.xml

source nec cfg 更新 閱讀 username 詳解 格式化sql BE 1:主配置文件主要分為三部分:    註意:通常情況下,一個session-factory節點代表一個數據庫;    1.1:第一部分       數據庫連接部分,註意"hibernate

Hibernate基礎知識

seq 每次 事務 name rep cfg 默認 poj 產生 一、Hibernate框架 Hibernate是一個開放源代碼的對象關系映射框架,它對 JDBC進行了非常輕量級的對象封裝,它將POJO類與數據庫表建立映射關系,是一個 全自動的ORM框架

WEB網站滲透技術

大拇指 一段 上傳 二次開發 們的 好好學習 提交 tar AR 有兩天沒發文章了,今天給大家來個大頭,那就是WEB網站滲透測試入侵教程 這個WEB網站滲透測試教程~是我見過的幾個少數的讓我看完就豎大拇指的教程 這部教程那可是我只能用棒棒的來形容說不出其他話來的 WEB網站

進階-中小型網絡構建-二層VLAN技術配實驗步驟

中小型網絡構建進階-中小型網絡構建-二層VLAN技術詳解配實驗步驟為什麽講 VLAN ? 在傳統的交換網絡中,為了隔離沖突域,我們引入了交換機。 交換機的每一個端口都是一個不同的隔離域。 但是交換機無法隔離廣播域, 所以,如果網絡中有一個惡意的主機發送廣播的惡意流量, 那麽處於同一個交換網路中的所有設備