概述
首先我們來了解緩存是什麼,解決什麼問題?
Cache是高速緩衝存儲器一種特殊的存儲器子系統,其中複製了頻繁使用的數據以利快速訪問;
凡是位於速度相差較大的兩種硬件/軟件之間的,用於協調兩者數據傳輸速度差異的結構,均可稱之爲Cache。
基於Web應用的系統架構圖
Web 應用系統存在哪些速度差異?
讀取文件系統→讀取磁盤
讀取數據庫內存→讀取文件系統
讀取應用內存→訪問數據庫服務器
讀取靜態文件→訪問應用服務器
讀取瀏覽器緩存→訪問網站
分類
其代表主要有操作系統、數據庫、應用程序、Web服務器和客戶端瀏覽器中,下面分別介紹:
操作系統磁盤緩存→減少磁盤機械操作
數據庫緩存→減少文件系統I/O
應用程序緩存→減少對數據庫的查詢
Web服務器緩存→減少應用服務器請求
客戶端瀏覽器緩存→減少對網站的訪問
操作系統
Windows的Disk Cache
Linux的Disk Cache
數據庫
數據庫緩存的重要性
爲什麼數據庫非常依賴緩存?
①數據庫通常是企業應用系統最核心的部分;
②數據庫保存的數據量通常非常龐大;
③數據庫查詢操作通常和頻繁,有時還很複雜;
④以上原因造成數據庫查詢會引起非常頻繁的磁盤I/O讀取操作,迫使CPU掛起等待,數據庫性能極度低下。
數據庫有哪些緩存策略?
①Query Cache;
②Data Buffer。
Query Cache
以SQL作爲key值緩存查詢結果集;
一旦查詢設計的表記錄被修改,緩存就會被自動刪除;
設置合適的Query Cache會極大提高數據庫性能;
Query Cache並非越大越好,過大的QueryCache會浪費內存;
MySQL:query_cache_size = 128M。
MySQLQuery Cache 監控工具
Show status like ‘Qcache%’;
Mysqlreport腳本;
MySQL Administrator。
Query Cache狀態demo
Data Buffer
data buffer是數據庫數據在內存中的容器;
data buffer的命中率直接決定了數據庫的性能;
data buffer越大越好,多多益善;
MySQL的InnoDB buffe:
Innodb_buffer_pool_size = 2G
MySQL建議buffer pool開大到服務器物理內存60%~80%。
MySQL buffer監控工具
show innpdb status\G;
show status like ‘innodb%’;
mysqlreport腳本;
innotop
InnoDB buffer狀態demo
應用程序
大概分爲:對象緩存;查詢緩存;頁面緩存:動態頁面靜態化;Servlet緩存;頁面內部緩存。下面分別介紹:
對象緩存
由O/R Mapping框架例如Hibernate提供,透明性訪問,細顆粒度緩存數據庫查詢結果,無需業務代碼顯示編程,是最省事的緩存策略。
當軟件結構按照O/R Mapping框架的要求進行針對性設計,使用對象緩存將會極大降低Web系統對於數據庫的訪問要求。
良好的設計數據庫結構和利用對象緩存,能夠提供極高的性能,對象緩存適合OLTP(聯機事務處理)應用。
對象緩存分類
對映射數據庫記錄的entity對象進行緩存。
對1對n關係的集合進行緩存。
對n對1的關聯對象進行緩存。
Hibernate對象緩存配置
配置entity對象緩存
@Entity
@Cache(usage =CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Forest{…}
配置關聯集合的緩存
@OneToMany(cascade =CascadeType.ALL,fetch = FectchTYPE.EAGER)
@JoinColumn(name = “CUST_ID”)
@Cache(usage =CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public SortedSetSet<Ticket>getTickets() { return tickets;}
僅僅添加Annotion就可以了,無需編碼,即可自動享受對象緩存。Hibernate會攔截對象的CRUD操作,針對對象讀取操作進行緩存,針對對象修改操作自動清理緩存。
Hibernate二級緩存是提升web應用性能的法寶
OLTP類型的Web應用,由於應用服務器端可以進行集羣水平擴展,最終的系統瓶頸總是逃不開數據庫訪問;
哪個框架能夠最大限度減少數據庫訪問,降低數據庫訪問壓力,哪個框架提供的性能就更高;
針對數據庫的緩存策略:
對象緩存:細顆粒度,針對表的記錄級別,透明化訪問,在不改變程序代碼的情況下可以極大提升web應用的性能。對象緩存是ORM的制勝法寶。
對象緩存的優劣取決於框架實現的水平,Hibernate是目前已知對象緩存最強大的開源ORM;
查詢緩存:粗顆粒度,針對查詢結果集,應用於數據實時化要求不高的應用。
查詢緩存
對數據庫查詢結果集進行緩存,類似數據庫的QueryCache;
適用於一些耗時,但是時效性要求比較低的場景。查詢緩存和對象緩存適用的場景不一樣,是互爲補充的;
當查詢結果集涉及的表記錄被修改以後,需要注意清理緩存。
Hibernate 查詢緩存
在配置文件中打開Query Cache
Hibernate.cache.use_query_cachetrue
在查詢的時候顯示編碼使用Cache
List blogs = sess.createQuery(“fromBlog blog where blog.blogger = :blogger”).setEntity(“blogger”,blogger).
setMaxResults(15).
setCacheable(true).
setCacheRegion(“frontpages”).
list().
Hibernate查詢緩存特徵
並非緩存整個查詢結果集,而是緩存查詢結果集entity對象的id集合。
[blog1,blog2,blog3,…];
在遍歷結果集的時候,再按照blogld去查詢blog對象,例如selectblog.* from where id = ?
如果此時blog配置了對象緩存,則自動讀取對象緩存。
Hibernate查詢緩存會自動清理過期緩存。
一旦結果集涉及的entity被修改,查詢緩存就被自動清理。
頁面緩存
頁面緩存的作用是什麼?
針對頁面的緩存技術不但可以減輕數據庫服務器壓力,還可以減輕應用服務器壓力;
好的頁面緩存可以極大提高頁面渲染速度;
頁面緩存的難點在於如何清理過期的緩存。
頁面緩存技術有哪些?
動態頁面靜態化;Servlet緩存;頁面局部緩存。
動態頁面靜態化
利用模板技術將訪問過一次的動態頁面生成靜態html,同時修改頁面鏈接,下一次請求直接訪問靜態鏈接頁面;
動態頁面靜態化技術的廣泛應用於互聯網CMS/新聞類Web應用,但也有BBS應用使用該技術,例如Discuz!
無法進行權限驗證,無法顯示個性化信息;
可以使用AJAX請求彌補動態頁面靜態化的某些缺點。
Servlet 緩存
針對URL訪問返回的頁面結果進行緩存,適用於粗粒度的頁面緩存,例如新聞發佈;
可以進行權限的檢查;
OScache提供了簡單的Servlet緩存(通過web.xml中的配置);
也可以自己編程實現Servlet緩存。
OSCache Servlet緩存demo
<fliter>
<filter-name>CacheFilter</filter-name>
<filter-class>com.opensymphony.oscache.web.filter.CacherFilter</filter-class>
<init-param>
<param-name>time<param-name>
<param-value>600<param-value>
</init-param>
</init-param>
<param-name>scope</param-name>
<param-value>session</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>/news/*</url-pattern>
</filter-mapping>
頁面局部緩存
針對動態網頁的局部片斷內容進行緩存,適用於一些個性化但不經常更行的頁面(例如博客);
OSCache提供了簡單的頁面緩存;
可以自行擴展JSP Tag實現頁面局部緩存。
CSCache的頁面局部緩存
<%@ taglib uri=http://opensymphony.com/oscache prefix=”cache”%>
<cache:cache>
…some jsp content…
</cache:cache>
<cache:cache key=”footbar”scope=”session”>
…some jsp content…
</cache:cache>
<cache:cache key=”<%=product.getId() %>” time=”1800” refresh=”<%= needRefresh %>”>
…some jsp content…
</cache:cache>
<cache:cache key=”,%product.getId() %” cron=”0 2 ***” refresh=”%= needRefresh %”>
…some jsp content…
</cache:cache>
Web服務器
EHCache
適合充當對象緩存個Hibernate繼承效果很好,GavinKing也是EHCache作者之一。
OSCache
充當Servlet和頁面緩存;在一個Web應用中可以同時使用OSCache和EHCache。
JBossCache
在JAVA集羣環境下使用;支持緩存在節點之前的複製,在JBossAS上被用來實現HTTP Session的內存複製功能。
非Java實現的通用緩存產品
Memcahed
在大規模互聯網下使用;
每秒支撐1.5萬~2萬次請求。
Tokyo Tyrant
兼容memcached協議,可以持久化存儲;
支持故障切換,對緩存器有高可靠性要求可以使用;
每秒支撐0.5萬~0.8萬次請求.
客戶端瀏覽器
基於 AJAX 技術的瀏覽器緩存
使用AJAX調用的時候,將數據庫在瀏覽器端緩存;
只要不離開當前頁面,不刷新當前頁面,就可以直接讀取緩存數據;
只適用於AJAX技術的頁面。
基於HTTP協議的資源緩存
基於資源的緩存demo
<filter>
<filter-name>CacheFilterStaticContent</filter-name>
<filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class>
<init-param>
<param-name>expires</param-name>
<param-vlaue>time</param-vlaue>
</init-param>
</filter>
<filter-mapping>
<filter-name>CacheFilterStaticContent</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
業務思想
關於緩存技術的介紹基本上就是個人的理解,其中,在很早以前個人對於緩存的理解呢,就是你的“速度”趕不上我的“速度”,我需要找個樹林歇一會兒等等你,就是緩存嘛。瞭解其基本原理還是很簡單的,大家有什麼補充的,歡迎交流。