Hibernate緩存策略html
緩存是數據庫數據臨時容器,它包含了庫表數據的臨時拷貝,位於數據庫與數據訪問層之間。linux
ORM 在進行數據讀取時,會根據其緩存管理策略,首先在內存中查詢,若是在內存中發現所需數據(緩存命中),則直接以此數據錯位查詢結果加以利用,從而避免了數據庫調用的性能開銷。數據庫
緩存的介質通常是內存,因此讀寫速度很快。但若是緩存中存放的數據量很是大時,也會用硬盤做爲緩存介質。緩存的實現不只僅要考慮存儲的介質,還要考慮到管理緩存的併發訪問和緩存數據的生命週期。緩存
緩存的範圍決定了緩存的生命週期以及能夠被誰訪問。緩存的範圍分爲三級。併發
1) 事物級緩存(Transaction Layer Cache )分佈式
緩存只能被當前事務訪問。緩存的生命週期依賴於事務的生命週期,當事務結束時,緩存也就結束生命週期。在此範圍下,緩存的介質是內存。事務能夠是數據庫事務或者應用事務,每一個事務都有獨自的緩存,緩存內的數據一般採用相互關聯的的對象形式。性能
2) 應用級/進程級緩存(Application/ProcessLayer Cache)spa
緩存被進程內的全部事務共享。這些事務有多是併發訪問緩存,所以必須對緩存採起必要的事務隔離機制。緩存的生命週期依 賴於進程的生命週期,進程結束時,緩存也就結束了生命週期。進程範圍的緩存可能會存放大量的數據,因此存放的介質能夠是內存或硬盤。緩存內的數據既能夠是 相互關聯的對象形式也能夠是對象的鬆散數據形式。hibernate
3) 集羣/分佈式緩存(Cluster Layer Cache)插件
在集羣環境中,緩存被一個機器或者多個機器的進程共享。緩存中的數據被複制到集羣環境中的每一個進程節點,進程間經過遠程通訊來保證緩存中的數據的一致性,緩存中的數據一般採用對象的鬆散數據形式。
對大多數應用來講,應該慎重地考慮是否須要使用集羣範圍的緩存,由於訪問的速度不必定會比直接訪問數據庫數據的速度快多少。
持久化層能夠提供多種範圍的緩存。若是在事務範圍的緩存中沒有查到相應的數據,還能夠到進程範圍或集羣範圍的緩存內查 詢,若是仍是沒有查到,那麼只有到數據庫中查詢。事務範圍的緩存是持久化層的第一級緩存,一般它是必需的;進程範圍或集羣範圍的緩存是持久化層的第二級緩 存,一般是可選的。
當多個併發的事務同時訪問持久化層的緩存的相同數據時,會引發併發問題,必須採用必要的事務隔離措施。
1) Read-only
只讀。對於歷來不會修改的數據,如參考數據,可使用這種併發訪問策略。
非嚴格讀寫。若是程序對併發訪問下的數據同步要求不是很是嚴格,且數據更新操做頻率較低(幾個小時以上),能夠採用這種併發訪問策略,得到較好的性能。
3) Read-write
嚴格讀寫。提供了Read Committed事務隔離級別。僅僅在非集羣的環境中適用。對於常常被讀但不多修改的數據,能夠採用這種隔離類型,由於它能夠防止髒讀這類的併發問題。
4) Transactional
事務。僅僅在託管環境中適用。它提供了Repeatable Read事務隔離級別。對於常常被讀但不多修改的數據,能夠採用這種隔離類型,由於它能夠防止髒讀和不可重複讀這類的併發問題。
事務型併發訪問策略是事務隔離級別最高,只讀型的隔離級別最低。事務隔離級別越高,併發性能就越低。
Hibernate中提供了兩級Cache,第一級別的緩存是Session級別的緩存,它是屬於事務範圍的緩存。這一 級別的緩存由hibernate管理的,通常狀況下無需進行干預;第二級別的緩存是SessionFactory級別的緩存,它是屬於進程範圍或羣集範圍 的緩存。這一級別的緩存能夠進行配置和更改,而且能夠動態加載和卸載。 Hibernate還爲查詢結果提供了一個查詢緩存,它依賴於第二級緩存。
|
第一級緩存 |
第二級緩存 |
存放數據的形式 |
相互關聯的持久化對象 |
對象的散裝數據 |
緩存的範圍 |
事務範圍,每一個事務都有單獨的第一級緩存 |
進程範圍或集羣範圍,緩存被同一個進程或集羣範圍內的全部事務共享 |
併發訪問策略 |
因爲每一個事務都擁有單獨的第一級緩存,不會出現併發問題,無需提供併發訪問策略 |
因爲多個事務會同時訪問第二級緩存中相同數據,所以必須提供適當的併發訪問策略,來保證特定的事務隔離級別 |
數據過時策略 |
沒有提供數據過時策略。處於一級緩存中的對象永遠不會過時,除非應用程序顯式清空緩存或者清除特定的對象 |
必須提供數據過時策略,如基於內存的緩存中的對象的最大數目,容許對象處於緩存中的最長時間,以及容許對象處於緩存中的最長空閒時間 |
物理存儲介質 |
內存 |
內存和硬盤。對象的散裝數據首先存放在基於內在的緩存中,當內存中對象的數目達到數據過時策略中指定上限時,就會把其他的對象寫入基於硬盤的緩存中。 |
緩存的軟件實現 |
在Hibernate的Session的實現中包含了緩存的實現 |
由第三方提供,Hibernate僅提供了緩存適配器(CacheProvider)。用於把特定的緩存插件集成到Hibernate中。 |
啓用緩存的方式 |
只要應用程序經過Session接口來執行保存、更新、刪除、加載和查詢數據庫數據的操做,Hibernate就會啓用第一級緩存,把數據庫中的數 據以對象的形式拷貝到緩存中,對於批量更新和批量刪除操做,若是不但願啓用第一級緩存,能夠繞過Hibernate API,直接經過JDBC API來執行指操做。 |
用戶能夠在單個類或類的單個集合的粒度上配置第二級緩存。若是類的實例被常常讀但不多被修改,就能夠考慮使用第二級緩存。只有爲某個類或集合配置了第二級緩存,Hibernate在運行時纔會把它的實例加入到第二級緩存中。 |
用戶管理緩存的方式 |
第一級緩存的物理介質爲內存,因爲內存容量有限,必須經過恰當的檢索策略和檢索方式來限制加載對象的數目。Session的evit()方法能夠顯式清空緩存中特定對象,但這種方法不值得推薦。 |
第二級緩存的物理介質能夠是內存和硬盤,所以第二級緩存能夠存放大量的數據,數據過時策略的maxElementsInMemory屬性值能夠控制 內存中的對象數目。管理第二級緩存主要包括兩個方面:選擇須要使用第二級緩存的持久類,設置合適的併發訪問策略:選擇緩存適配器,設置合適的數據過時策 略。 |
1) 適合存放到二級緩存中的數據
不多被修改的數據
不是很重要的數據,容許出現偶爾併發的數據
不會被併發訪問的數據
參考數據
2) 不適合存放到二級緩存的數據
常常被修改的數據
財務數據,絕對不容許出現併發
與其餘應用共享的數據。
1) 條件查詢的時候,老是發出一條select * from table_name where …. (選擇全部字段)這樣的SQL語句查詢數據庫,一次得到全部的數據對象。
2) 把得到的全部數據對象根據ID放入到第二級緩存中。
3) 當Hibernate根據ID訪問數據對象的時候,首先從Session一級緩存中查;查不到,若是配置了二級緩存,那麼從二級緩存中查;查不到,再查詢數據庫,把結果按照ID放入到緩存。
4) 刪除、更新、增長數據的時候,同時更新緩存。
Hibernate的二級緩存策略,是針對於ID查詢的緩存策略,對於條件查詢則毫無做用。爲此,Hibernate提供了針對條件查詢的Query緩存。
1) Hibernate首先根據這些信息組成一個QueryKey,Query Key包括條件查詢的請求通常信息:SQL, SQL須要的參數,記錄範圍(起始位置rowStart,最大記錄個數maxRows),等。
2) Hibernate根據這個Query Key到Query緩存中查找對應的結果列表。若是存在,那麼返回這個結果列表;若是不存在,查詢數據庫,獲取結果列表,把整個結果列表根據Query Key放入到Query緩存中。
3) Query Key中的SQL涉及到一些表名,若是這些表的任何數據發生修改、刪除、增長等操做,這些相關的Query Key都要從緩存中清空。