程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> ASP編程 >> ASP技巧 >> 理解web緩存

理解web緩存

編輯:ASP技巧

Q:什麼樣的緩存才是好緩存?

能解決問題的緩存就是好緩存。這句話簡直就是廢話,相當於白貓、黑貓,抓住老鼠的就是好貓。

那在解決問題前提下,哪個緩存才是好緩存呢? 這個問題我的答案是:緩存命中率高的緩存是好緩存。

在解決問題前提下,命中率高的緩存比命中率低的緩存,在硬件投入上可能會比較小,同時緩存的數量比命中率低的緩存數量也可能少,這樣尋址的速度 肯定比較快。所以命中率高的緩存是好緩存。


緩存的命中率

一個緩存的實體在被丟到緩存中後,在這個實體被緩存的期間(這個實體被緩存的生命周期內),如果外部一次都沒有使用過它,這個緩存實體的命中率 就是0。這個實體被請求的次數越多,它的緩存命中率越高。

上面說的是緩存中一個實體的命中率。對於緩存整體來說,它的命中率則是上面各個被緩存的個體的命中率分布圖。

對於緩存來說:通常最常使用的個體之占總體的很小一部分。最不常使用的占整體的很大一部分。


所以我們經常會看到類似這樣的數據:

緩存的1萬個元素中,有100個被頻繁的使用,幾乎每分鐘都會被使用一次。2000個數據,每小時被請求一次。3000個數據,每天被請求一 次,剩下的數據,被丟到緩存中後一次都沒有被使用過。

現在硬件發展很快,如果我們只是需要緩存1萬個數據的話,我們完全可以做到不管這1萬個數據是否被使用到,全部丟到緩存,這樣只要找數據,肯定 緩存中有這個數據。而不需要作額外的運算,或者不需要向數據庫發出請求。

但是:硬件發展快,數據量發展也快。小型的網站,緩存1萬條數據,也就全部緩存了。但是大型網站最少也是上百萬的數據量或者上T級別的數據,這 些數據量顯然不能都丟到緩存。這時候設計一個合理的緩存方案,提高緩存的命中率,就非常重要。而且是必須的。

提高緩存命中率的一些常見方法

純技術的角度來說,我們只有記錄了用戶的單位時間的請求數,並依照這個信息來把最常被使用的數據緩存起來。

但更多的時候,我們是根據業務邏輯來提高緩存命中率的。比如:去年,前年發表的博客,這類文章的浏覽請求,一般一天至少可憐的幾次。一般不應該 緩存到內存中。

又比如,回復數多的帖子,一般被請求數會比回復數少的帖子會被更多人次看到。

我們應該通過上面邏輯,根據我們實際業務邏輯,提供一個緩存算法,提高緩存的命中率。讓在我們硬件允許的條件下,緩存適當的數據,而不是所有數 據。

一個反面的例子就是:不管三七二十一,一個大型的博客站點,一篇文章被用戶請求的時候,發現不在內存緩存中,就從數據庫中讀出,然後丟到緩存。

要知道,現在爬蟲程序很多的。另外,博客這類搜索引擎友好的站點,決大多數的訪問壓力是搜索引擎搜索過來的。而這些訪問一般都是1小時,或者1 天之內,對某篇文章只有幾次甚至1次請求,之後再也沒有了。上面作緩存的方法,命中率會非常低的。

這裡也許就有人會問,郭紅俊,既然你不建議我緩存這些博客的內容,但是我如何提高我站點的性能呀,我至少得保證我博客站點不會速度慢的無法響應 用戶請求呀。

這個問題的解決方案有很多,一個最簡單的方法就是把這些博客做成靜態Html頁面,也就是文件系統的緩存,文件系統因為硬盤的原因,可以簡單理 解成可以無限擴容,這樣就可以把很多命中率低的內容進行緩存。

如果你的頁面需要一些動態邏輯判斷,你可以把數據緩存成xml文件,然後服務器段整合這些XML文件,或者是包含文件。這也是種不錯的方法。

說了這麼多緩存命中率的問題,簡單匯總一下緩存命中率的觀點:

小型網站可以全部數據緩存,一般壓力也不會很大,可以忽略緩存命中率問題。
大型服務無法全部數據緩存,只能部分數據緩存,這時候就需要架構師設計出對該業務邏輯適用的緩存方法,盡可能的提高緩存的命中率。
提高命中率的方法大多是跟業務邏輯捆綁的,需要跟具體問題具體分析
對於不能被內存緩存的數據,最簡單的提高性能方法就是使用文件緩存。
文件緩存可以整個內容緩存成一個靜態文件;也可以是整個頁面的一個區域被緩存成一個文件,然後被包含;也可以是把一個實體序列化成XML 文件進行緩存。
下面我們看看緩存的其他幾個不那麼重要的方面:

緩存的生命周期內的活動

永久不過期,永久不變更的內容,這類東西就不應該放在緩存。緩存是臨時的存儲,而不是永久的,所以緩存的生命周期是有限的。

它依次可能會經歷如下活動:

進入緩存。(進入緩存的時候,可能需要指定它以後的過期策略,如果不指定,需要使用系統默認的過期策略)
從緩存中獲得它,注意,這時候需要處理線程安全的問題。
更新緩存,注意,也需要考慮線程安全問題
離開緩存,這個可能是外部請求,也可能是緩存根據過期策略把它清理掉。
緩存的過期策略

一般我會問,你所接觸的緩存中,碰到過那些緩存過期策略?

最常見的幾種過期策略如下:

多長時間沒有被請求,則過期,最典型的就是asp和ASP.Net 提供的 Section 功能。其實它就是一個緩存。

依賴於文件變更的緩存,一旦文件被修改,緩存則過期,典型的是 WEB站點的 Web.config ,一旦這個文件變更,不但緩存重起,IIS進程也會進行一次釋放工作。

在此基礎上,可能看到很多依賴關系的緩存過期策略。比如依賴於數據庫的緩存過期策略。

當然,業務邏輯裡可能會有更復雜的過期策略,必須CSDN新版積分制論壇中,帖子列表緩存會在列表數據緩存達到600時,把它清理到550條數 據。

又比如新積分制論壇帖子的緩存過期,則是沒有任何列表引用這個帖子後,則這個帖子過期。

緩存的同步問題

使用緩存,則意味著同樣的數據,可能有多份並存。如果你的代碼沒有考慮某種情況,導致了這兩份數據不一致了。這時候就會有問題發生。

解決方法很簡單,把你的業務邏輯,代碼觸發情況都考慮清楚,不要遺留沒有觸底的地方。

簡單的方法會導致你的代碼邏輯變得非常復雜。

這也就是有些人,在非必要的時候,建議你不要用緩存的原因。一旦開始使用緩存,你就應該准備增加大量的代碼來處理數據同步的問題。

初始化填充緩存數據

有時候在緩存被初始化後,還需要預先填充一些數據到緩存中。這就是緩存數據的初始化操作。

緩存數據的初始化操作需要考慮以下問題:

需要多長時間進行初始化,一般如果是站點的話,我們可能在 Global.asa 的 application_OnStart 中處理這個初始化工作。初始化的一般不能太久,這時候就是考驗我們代碼優化的能力了。
初始化的時候,一般是批量導入數據,而不是我們正常使用的時候,一次處理一個數據。
總結:

本文介紹了我對緩存的一些觀點,而沒有深入涉及到具體的緩存技術。希望通過本文的講述,讓只會緩存用法不懂緩存思想的人有初步的了解。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved