設計緩存的目的
緩存模塊可以用來實現下列功能:
- 提供了一系列的API
- 它使得開發者不需要學習很多內部的工作機制,就可以將常用的緩存功能加入應用
- 使用企業庫的配置工具很容易配置
- 性能高效
- 線程安全,內部的代碼考慮到了在多個線程調用,沒有非預期的內部交互。
- 使用后端存儲,使得發生以外也可以保持數據的完整無缺。
- 保證了內存中的數據和后端存儲保持數據同步。
本節講述一些緩存模塊設計的亮點,和設計的細節。還包括一些過期處理的設計和掃描處理的設計。
1、設計亮點
上圖顯示的是緩存模塊中關鍵類之間的關系。
當你用CacheFactory初始化一個CacheManager對象的時候,在內部創建了一個CacheManagerFactory對象,創建了一個Cache對象。常見Cache對象之后,在后端存儲的所有數據被加載到內存中,放在Cache對象中。然后應用可以用CacheManager發出請求,獲取數據添加數據,刪除數據。
當應用向CacheManager發送請求,使用GetData方法從緩存中獲取數據的時候,CacheManager對象會請求Cache對象。如果請求項存在的話,返回緩存的數據,如果不存在返回null,如果對象過期,也返回null。
當應用使用CacheManager的add方法,向緩存中添加項的時候,CacheManager同樣將請求發送給Cache對象。如果已經存在一個同樣key的項的話,Cache首先會刪除原來的項,然后加入新項。如果緩存的后端存儲是默認的NullBackingStore,數據只是寫入內存。如果添加項的時候,達到了緩存存儲數據量的上限的話,BackgroundSchedule對象就會開始掃描,進行過期處理。
如果添加的項在內存緩存中沒有的話,Cache首先創建一個復制品,然后添加到內存的hashtable中,然后鎖定內存中的項,添加項到后端存儲,然后替代內存hashtable中的項。如果在寫入后端存儲的時候發生異常,就會從內存緩存中刪除那個復制品。緩存模塊擁有很強的異常安全保護,意味著如果加入項的時候發生異常,緩存的狀態可以回滾的添加之前的狀態。換句話說,除非添加項成功,否則緩存的狀態不會改變。(同樣也適用于刪除項和清空項)
BackgroundSchedule對象周期性的監測緩存中的項。當一個項過期,BackgroundSchedule首先會移除項,然后有可能會通知應用,項被移除。這時候,應用的責任就是更新緩存。
2、設計細節
CacheManager是一個接口類型,所有的緩存操作都通過接口調用。如果開發者沒有修改直接使用緩存模塊的話,CacheManager對象提供了訪問緩存需要的全部方法,獲取、添加、刪除、清空項。每個方法都是線程安全的。
使用CacheFactory類創建一個CacheManager對象,還會創建一個CacheManagerFactory類。CacheManagerFactory類會創建實現一個CacheManager所需要的內部類。
不同的緩存不能共享相同的后端儲存,每個CacheManager都只能對應一個后端存儲。Cache對象接收從CacheManager對象發送過來的請求,實現了所有的在內存緩存和后端儲存之間的操作。包含了一個hashtable來存儲內存中對應的數據,一個數據項作為一個CacheItem對象。這個對象包括數據本身,還包括了項的key,優先級,RefreshAction對象,和過期策略。這些信息都存放在一個hashtable中,Cache也是線程安全的。Cache用一個同步的hashtable控制應用和BackgroundSchedule對緩存中的項的訪問。
BackgroundSchedule對象的責任就是進行過期處理,掃描低級別的項。PollTimer對象激活過期循環,一個數字是一次掃描處理移除的項目。這些都在配置文件中可以設置。
緩存模塊中的緩存存儲類包括DataBackingStore、IsolateStorageBackingStore、和NullBackingStore。如果你想要實現自定義的后端存儲,你需要實現IBackingStore接口,或者是繼承BaseBackingStore類,這個類也實現了IBackingStore接口。這個基類包含了實現任何后端存儲所需要的策略和工具方法。
當后段存儲是使用數據庫的時候,可以用DataBackingStore類。在配置工具中,對應于一個數據庫實例的名稱。
DataBackingStroe和IsolatedBackingStore類可以在持久化之前加密緩存項。加密緩存項可以通過配置來激活。使用配置工具,緩存存儲可以使用配置好的加密算法provider。provider的name在從緩存中讀取數據,然后在顯示之前解密的時候同樣需要。
? 過期策略的設計
緩存模塊的過期處理是靠BackgroundSchedule來執行的。它會周期性的檢查hashtable中的緩存項,看是否有過期項。你可以在配置緩存模塊的時候設置檢查周期的時間。
緩存模塊提供了四個過期策略:
- Absolute,意味著緩存項在一個特定的時間過期
- Sliding,意味著緩存項在最后一次訪問之后的固定時間過期,默認為2分鐘。
- Expended format,你可以詳細描述過期條件,例如,可以設定為每個星期六晚上10:00,或者是每個月的第三個星期日。Expended formats在ExpendedFormat.cs文件中列出來很多。
- File dependency,意味著當一個文件被修改,緩存項就過期
前三個過期選項都是以時間為基礎的,如果數據的更新時間是規則的,或者是在一個特定的時間更新,你可以使用前三個選項。
第四個,文件依賴,是以通知為基礎的。它指定緩存項的過期依賴一個特定的文件,如果文件被修改,緩存項就過期,就會刪除緩存項。
Add方法有兩個重載,一個設置了默認的過期策略,NeverExpired。另外一個你可以設置適合自己的過期策略。你甚至可以設置自定義的策略,如果你為一個緩存項設置了多個策略, 如果由一個策略符合條件,緩存項就會過期。
標記和清除
過期包括兩個步驟。一個就是標記,另外一個就是清除。分為兩個步驟,就是為了避免BackgroundSchedule清除一個應用正在使用的緩存項可能發生的沖突。
在標記過程中,BackgroundSchedule會拷貝一份hashtable,然后檢查里面的每一個緩存項,看看有沒有過期的。這時候會鎖定緩存項,如果發現過期的,就會打個標記。
在清除過程中,BackgroundSchedule會重新檢查緩存項的標記,看看在打上標記之后是否有訪問記錄。如果有訪問記錄,就保留緩存項。如果沒有,就過期它,刪除它。緩存項過期的時候,會引發WMI事件。
回調callbacks
開發者可以選擇add方法的另外一個重載,使得在緩存項過期,刪除緩存項的時候發通知給應用,如果有必要,應用可以更新緩存。
掃描處理的設計
緩存模塊的掃描處理也是由BackgroundSchedule執行的。在每次有緩存項加入的時候都會檢查,緩存項的數目是否達到設置的最大值。數量是設置在CacheManager實例上的。
當加入一個緩存項的時候,可以設置優先級,有四個選項:Low,Normal,High,NotRemovable。刪除的時候會按照優先級的高低進行處理,優先級低的會先被清除。默認值是Normal。
當你想讓一個緩存項直到它過期才被清除的話,可以設置為NotRemovable。最好不要設置為NotRemovable,因為緩存是用來提升性能的,不應該被作為一種持久化手段。
不想過期處理包括兩個過程,掃描處理只有一個過程。
?
?
未完待續。。。。。。。。。。。。。。。。。。。。。。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
