粗淺看 緩存技術

概述

首先我們來了解緩存是什麼,解決什麼問題?

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>

業務思想

關於緩存技術的介紹基本上就是個人的理解,其中,在很早以前個人對於緩存的理解呢,就是你的“速度”趕不上我的“速度”,我需要找個樹林歇一會兒等等你,就是緩存嘛。瞭解其基本原理還是很簡單的,大家有什麼補充的,歡迎交流。

 

發佈了144 篇原創文章 · 獲贊 12 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章