程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> AppFabric緩存-實際應用與集成

AppFabric緩存-實際應用與集成

編輯:關於.NET

Microsoft Windows Server AppFabric 以前的代號是“Velocity”,提供了可以集成到 Web 應用程序和桌面應用程序的分散式緩存。AppFabric 能夠提高性能、可伸縮性和可用性,而從開發人員的角度來看,其行為方式與普通的內存緩存一樣。任何可序列化的對象都可以緩存,例如 DataSet、DataTable、二進制數據、XML、自定義實體以及數據傳輸對象。

AppFabric 客戶端 API 簡單易用,服務器 API 則具備全功能的分布式資源管理器 (DRM),該工具可以管理一個或多個緩存服務器(多個服務器構成一個緩存群集)。每個服務器將提供各自的內存份額,執行各自的對象序列化與傳輸、區域分組、基於標簽的搜索和過期關閉。緩存服務器還支持高可用性,借助該功能可在備用服務器上創建對象副本。

2009 年 6 月號的 MSDN 雜志 中包含一篇對 Windows Server AppFabric 的精彩介紹,作者是 Aaron Dunnington (msdn.microsoft.com/magazine/dd861287)。在本文中,我將說明如何將 AppFabric 緩存集成到桌面和 Web 應用程序中。與此同時,我會提供一些最佳實踐,並針對如何利用 Microsoft .NET Framework 4 和 ASP.NET 4 中的新增功能給出一些提示。您還可以了解如何解決在使用分布式緩存時常見的問題。

接下來的所有代碼示例均來自一個名為 Velocity Shop 的完整演示解決方案,該方案可以從 Codeplex 上獲得,網址為:velocityshop.codeplex.com。

請注意,本文中將要討論的 Windows Server AppFabric 不同於 Windows Azure 平台的 AppFabric。有關 Windows Azure 技術的更多信息,請參見 microsoft.com/windowsazure/appfabric。

入門

目前的 Windows Server AppFabric Beta 2 Refresh 可以通過幾種方式來安裝,以用於開發。借助 Web Platform Installer (microsoft.com/web/downloads),可以通過一個可配置的安裝包輕松安裝各種 Web 開發應用程序和框架。不僅如此,Web Platform Installer 還會進行更新,以便包括新發行的受支持的應用程序和框架。

如果只想安裝 AppFabric,則可以訪問 Windows Server 開發人員中心的 Windows Server AppFabric 頁面,其中包含一個指向最新發行版的鏈接。該頁面的網址為:msdn.microsoft.com/windowsserver/ee695849。

安裝程序完成後,AppFabric 緩存差不多已經可以使用。下一步是創建一個命名緩存,即用於存儲數據的邏輯容器。可以通過 Windows PowerShell 中的 New-Cache cmdlet 來執行此操作:

New-Cache -cacheName Catalog

若要開始在應用程序中使用 AppFabric 緩存,只需在 Visual Studio 項目中添加對 CacheBaseLibrary.dll、CASBase.dll、CASMain.dll 和 ClientLibrary.dll 的引用即可。

客戶端庫簡單明了。以下代碼顯示了如何訪問分布式緩存以便訪問命名緩存,以及如何存儲或檢索對象:

cacheCluster = new DataCacheServerEndpoint[1];
cacheCluster[0] = new DataCacheServerEndpoint(
  "ServerName", 22233, "DistributedCacheService");
DataCacheFactory factory =
  new DataCacheFactory(cacheCluster, true, false);
DataCache cache = factory.GetCache("Catalog");

// Putting a product in cache
cache.Put("Product100", myProduct);

// Getting Product from cache
Product p = (Product)cache.Get("Product100");

在開始使用 AppFabric 緩存之前,最好是制定一些計劃。第一步是考慮如何設置緩存。這決定了可以在應用程序中利用 AppFabric 緩存的哪些功能。

最開始,需要為您的項目設置一個命名緩存,如前所述。設置好後,可以自定義過期和通知策略。各個對象或集合可能需要不同的緩存持續時間,並且在內存過於緊張時合理地從緩存中刪除(或者不刪除)。若要為指定的命名緩存設置絕對過期超時時間,可使用帶 TTL 參數的 New-Cache cmdlet。

除了命名緩存外,您可能還需要配置區域。這些區域就像緩存中的子組,可用來組織對象,從而簡化在緩存中查找對象的過程。例如,我的應用程序使用一個消費電子設備目錄。那麼我可以創建一個名為“目錄”的緩存,在其中將我的產品劃分到名為“電視機”、“照相/攝像機”和“MP3 播放器”的區域中。您只能在運行時創建區域,為此,需要使用 dataCache.CreateRegion 方法,並提供區域名稱:

// Always test if region exists;
try {
  cache.CreateRegion("Televisions", false);
}
catch (DataCacheException dcex) {
  // if region already exists it's ok,
  // otherwise rethrow the exception
  if (dcex.ErrorCode != DataCacheErrorCode.RegionAlreadyExists)
   throw dcex;
}

請記住,如果已經存在同名的區域,將引發 DataCacheException 錯誤,因此您必須使用恰當的 try-catch 塊。

但如果您需要根據功能來搜索產品呢?這時就可以使用 AppFabric 緩存的另一項有用功能:基於標簽的搜索。該功能只在使用區域時可用,它可以為緩存中駐存的每項附加一個或多個標簽,用於以後的搜索。

例如,我想找到“電視機”區域中帶“LED 顯示屏”和“46 英寸”標簽的所有產品,那麼我需要使用 GetByAllTags 方法,指定 DataCacheTags 列表,就這樣。以下是一個基於標簽的搜索示例:

DataCacheServerEndpoint[] cacheCluster = GetClusterEndpoints();
DataCacheFactory factory =
  new DataCacheFactory(cacheCluster, true, false);
DataCache cache = factory.GetCache("Catalog");
IEnumerable<KeyValuePair<string, object>> itemsByTag =
  cache.GetObjectsByTag(
  new DataCacheTag("LED-Panel"), "Televisions");

在現有或新的應用程序中引入緩存層時,您還必須考慮到一些常見問題。這樣有助於標識和區分可用於緩存的數據類型。以下就是三個類別:

引用數據,這包括不會經常發生變化的只讀數據(如果有),例如國家/地區列表、一般儲備項的目錄或者產品數據表。

活動數據,這包括會根據每個用戶或會話發生變化的數據,例如購物車或意向清單。

資源數據,這類信息常常會發生變化並且受多個用戶活動類型的影響,例如產品庫存在用戶下訂單後發生的變化。

這種分類有利於為每個命名緩存指定過期和通知策略,使您能夠合理有效地利用資源。請記住,即便您可以向群集中添加緩存服務器,內存資源也始終是有限的。

緩存生命周期

當應用程序啟動時,緩存是空的。但是用戶要訪問網站。那麼如何准備好緩存呢?

由於使用直接緩存模式,因此當請求的數據不在緩存中時,啟用緩存的應用程序必須能夠切換到永久存儲中,例如 SQL Server 數據庫。但是在數據量很大的情況下,此過程的消耗也可能很大,尤其是在處理大量引用數據時,或者無法保證緩存加載的唯一性時。在某個特定的時候,可能會有多個線程針對某一對象檢驗緩存,隨後嘗試從存儲中加載數據,並將數據駐存在緩存中用於以後的請求。由於既要提取未經緩存的數據,又要不必要地頻繁執行數據緩存,因此會導致性能降低。

這時,類似於 IIS 7.5 服務自動啟動之類的功能就派得上用場了。借助 AppFabric,您可以使用讀取器鎖來獲得相似的結果。若要啟用服務自動啟動功能,必須對 applicationHost.config 進行一些更改,如下所示:

<serviceAutoStartProviders>
  <add name="PrewarmMyApp"
     type="MyWebApp.PreWarmUp, MyWebApp" />
</serviceAutoStartProviders>

接下來,使用自定義代碼實現 Preload 方法,將引用數據和資源數據載入命名緩存中:

using System.Web.Hosting;
namespace DemoApp {
  public class WarmUp : IProcessHostPreloadClient {
   public void Preload(string[] parameters) {
    // Cache preload code here...
   }
  }
}

這使 Web 應用程序僅在 Preload 方法執行完之後可用。

在如圖 1 所示的服務器場方案中,還有另外一個問題:每個冷啟動的應用程序需要訪問永久存儲以加載其緩存。默認的 ASP.NET 緩存綁定到用來運行應用程序的 appDomain,因此您只執行一次緩存加載操作。但在 AppFabric 中,緩存可以在各個 Web 服務器之間共享,從而在各個 Web 應用程序之間共享,因此能避免並行的緩存加載嘗試。

圖 1 服務器場中的 AppFabric 緩存

將緩存加載委托給單個服務器有多種選擇。AppFabric Beta 1 中引入了讀取器鎖這種功能。借助該功能,您可以在緩存項密鑰添加到緩存之前將其鎖定。只有第一個鎖定密鑰的預加載代碼才能啟動與其關聯的數據加載。這就像在緩存加載期間,在使用密鑰之前預定密鑰。您還可以利用該技術在各個 Web 服務器之間分發緩存加載操作。您可以預先對每個服務器進行配置,使其加載與特定的預定密鑰關聯的數據。

了解何時加載緩存是一個常見的與分布式資源(如緩存群集)相關的同步問題。利用 AppFabric 緩存,可以通過幾種方法來確定緩存何時就緒。一種方法是讓服務器在加載各自預定的密鑰數據之後輪詢公共密鑰。另外的方法包括,訂閱緩存就緒通知,甚至可以在一個單獨的服務或應用程序中執行預加載階段,這是因為緩存現在是分布式的,從 Web 和桌面應用程序中都可以訪問。

另外,還可以利用 .NET Framework 4 的 System.Threading.Tasks.Parallel 類來並行執行多個緩存加載操作,如圖 2 所示。

圖 2 並行的緩存加載

// load catalog items from DB 
SQLServerCatalogProvider SQLServerCatalogProvider =
  new SQLServerCatalogProvider();
itemsInCategory =
  SQLServerCatalogProvider.GetItemsByCategoryId(categoryId);
_helper.CreateRegion(categoryId);

Parallel.ForEach(itemsInCategory, item =>{
  // put each catalog item in cache with tags
  if (item.Tags==string.Empty)
   _helper.PutInCache(item.ProductId, item, categoryId);
  else
   _helper.PutInCache(item.ProductId, item, categoryId, item.Tags);
});

// Code from Helper class
public void PutInCache(string key, object value,
  string region, string tags) {

  List<DataCacheTag> itemTags = new List<DataCacheTag>();

  foreach (var t in tags.Split(',').ToList())
   itemTags.Add(new DataCacheTag(t.ToLower()));
  _cache.Put(key, value, itemTags , region);
}

在以後的 AppFabric 緩存版本中,計劃增加緩存遍歷功能。這樣當數據不存在時,您就能夠自動運行自定義代碼來加載緩存;與此相反,當緩存中的信息已更新時,就將數據保存到永久存儲中。

ASP.NET 集成

借助 ASP.NET 提供程序模型,開發人員可以從三種會話提供程序中進行選擇:InProc、StateServer 和 SQLServer。使用 AppFabric 緩存時,第四個會話提供程序在技術上是可行的,但是應當小心不要將會話與緩存混淆。緩存用於提高性能,會話用於使應用程序達到一定的狀態。

用於 ASP.NET 的 AppFabric 緩存會話提供程序使用其分布式緩存(可能具有高可用性)作為 ASP.NET 會話的存儲庫。這一功能是透明的,且無需打斷現有的代碼便可以使用。有了這樣的提供程序,ASP.NET 會話就可以在 Web 服務器崩潰或脫機的情況下保持可用,這是因為,會話是另外存儲在 AppFabric 緩存中的。

安裝並配置完 AppFabric 緩存之後,您必須創建一個命名緩存來存儲 ASP.NET 會話。然後就可以通過修改 Web.config 來啟用 DataCacheSessionStoreProvider,如圖 3 所示。

圖 3 在 AppFabric 緩存中啟用 ASP.NET 會話

<?xml version="1.0"?>
<configuration>
  <configSections>
   <section name="dataCacheClient"
    type="Microsoft.Data.Caching.DataCacheClientSection, CacheBaseLibrary"
    allowLocation="true" allowDefinition="Everywhere"/>
   <section name="fabric"
    type="System.Data.Fabric.Common.ConfigFile, FabricCommon"
    allowLocation="true" allowDefinition="Everywhere"/>
   <!-- Velocity 1 of 3 END -->
  </configSections>
  <dataCacheClient deployment="routing">
   <localCache isEnabled="false"/>
   <hosts>
    <!--List of services -->
    <host name="localhost" cachePort="22233"
     cacheHostName="DistributedCacheService"/>
   </hosts>
  </dataCacheClient>
  <fabric>
   <section name="logging" path="">
    <collection name="sinks" collectionType="list">
     <!--LOG SINK CONFIGURATION-->
     <!--defaultLevel values: -1=no tracing;
       0=Errors only;
       1=Warnings and Errors only;
       2=Information, Warnings and Errors;
       3=Verbose (all event information)-->
     <customType
      className="System.Data.Fabric.Common.EventLogger,FabricCommon"
      sinkName="System.Data.Fabric.Common.ConsoleSink,FabricCommon"
      sinkParam="" defaultLevel="-1"/>
     <customType
      className="System.Data.Fabric.Common.EventLogger,FabricCommon"
      sinkName="System.Data.Fabric.Common.FileEventSink,FabricCommon"
      sinkParam="DcacheLog/dd-hh-mm" defaultLevel="-1"/>
     <customType
      className="System.Data.Fabric.Common.EventLogger,FabricCommon"
      sinkName="Microsoft.Data.Caching.ETWSink, CacheBaseLibrary"
      sinkParam="" defaultLevel="-1"/>
    </collection>
   </section>
  </fabric>
<appSettings/>
<connectionStrings/>
<system.web>
  <sessionState mode="Custom" customProvider="Velocity">
   <providers>
    <add name="Velocity"
     type="Microsoft.Data.Caching.DataCacheSessionStoreProvider, ClientLibrary"
     cacheName="session"/>
   </providers>
  </sessionState>
...

由於只有服務器一端需要使用 .NET Framework 4,而客戶端庫使用 .NET Framework 3.5 和 4 均可,因此您可以將 AppFabric 緩存集成到現有的 ASP.NET 3.5 應用程序中。

ASP.NET 4 的另一個擴展點是輸出緩存。從 ASP.NET 1.0 版本以來,已經能夠將生成的頁面和控件輸出存儲在內存緩存中。後續請求可以從內存中獲取此輸出而不用再次生成。ASP.NET 4 支持配置一個或多個自定義輸出緩存提供程序。ASP.NET 4 後將會提供 AppFabric 輸出緩存提供程序,您也可以通過擴展 OutputCacheProvider 類和修改 Web.config 來自行啟用。

ORM 集成

多數常用的對象關系映射 (ORM) 框架具備名為二級緩存的功能。二級緩存是一個存儲庫,用於在一段可配置的時間內存儲實體、集合和查詢結果。如果要從永久存儲中加載某個實體,ORM 會首先檢驗二級緩存中是否已經加載了該實體。如果已經存在,則會向調用代碼傳遞一個所請求實體的實例,而不需要直接訪問數據庫。

每個 ORM 實現都有各自用來處理實體關聯、集合與查詢結果的策略,這對二級緩存也同樣適用。根據您所使用的 ORM,您可能會發現自己的二級緩存自定義和消耗選項是有限的,這迫使您不得不采用特殊的方法來消耗緩存更改。例如,如果過期策略和緩存依賴關系難以自定義,則對象爭用情況可能會增加,而緩存效率會降低。

NHibernate 和實體框架都可以使用 AppFabric 緩存作為二級緩存。Nhibernate 通過 nhibernate.caches.velocity 來啟用此功能 (sourceforge.net/projects/nhcontrib/files/NHibernate.Caches/)。實體框架通過由 Jaroslaw Kowalski 提供的 EFCachingProvider 來啟用此功能 (code.msdn.microsoft.com/EFProviderWrappers)。

開始運行 AppFabric

正如您所看到的,利用 Windows Server AppFabric 緩存可以輕松地在任何新的或現有的應用程序中啟用群集級別的緩存。若要充分發揮緩存的優勢,您需要標識適當的候選數據對象(您可能已經對本地服務器緩存執行了這一操作)。此外,還需要定義過期和通知策略。

AppFabric 在 Windows Server 2008 許可證中提供,也可以從以下網址下載:msdn.microsoft.com/windowsserver/ee695849。它還在 Windows Azure 中作為“緩存”角色存在。

下載 AppFabric,設置單/多服務器緩存群集;如果您有興趣,下載並在 CodePlex 上運行 Velocity Shop,以快速評估和體驗該解決方案內演示的所有 AppFabric 功能。

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