MSDN Flash – Windows Azure 新功能(4): 分散式快取服務 - Windows Azure Cache Service


雲端運算的特色之一,就是近乎無限的運算與儲存能力,為了達成這個目標,雲端供應商無不大肆擴充所屬資料中心機房與伺服器數量,以加強自身雲端平台的運算與儲存擴充性,而為了支援這些服務,在雲端資料中心內會以 Grouping(群組化)與集中區域的方式部署伺服器與儲存體,包含 SAN 以及 Server Clusters,透過群組集中的方式降低伺服器與儲存間的網路存取負擔,可提升小部份的存取效能。

運算服務在雲端運算中較不會受到存取影響,但儲存一定會受到 I/O 速度的影響,尤其是雲端平台的供應商為了節省建置伺服器資源所需的成本,多數的伺服器都不是外界所想像的高檔(硬碟可能只是 SATA 7,200RPM 的 250GB 硬碟,市價一顆可能只要 2,000 元左右或不到),那麼提升 I/O 的速度就成為雲端平台供應商的重點工作了。特別是在雲端平台這種大量且分散式的存取,像是 NOSQL(Not Only SQL)的分散式資料存取工作,若資料都要由磁碟存取的話,應用程式的 I/O 效率一定會受到極大的影響,原因很簡單,分散式儲存(Distributed Storages)是需要向負責儲存的伺服器群組要求讀寫資料,而在分散式儲存架構中,可劃分為索引伺服器(index server)與儲存伺服器(storage server),索引伺服器會接收來自應用程式的儲存讀寫需求,並將讀寫指令導向正確的儲存位置,再由儲存伺服器負責讀寫,因此時間會是索引伺服器的搜尋時間加上儲存伺服器的讀寫時間。雖然可以在儲存伺服器上加上 Buffer 或緩衝的功能讓 I/O 加速,但是無法顯著的改善效能。

因此,就有專家想出在指令進入索引伺服器前就得到資料的構想,也就是在分散式儲存服務前,加上一道可以快取應用程式資料的程序(這些程序也會以 HA/Cluster 與 Load Balancing 的方式建構),而這些程序可以將資料保存在自己的記憶空間中,當應用程式想自分散式儲存讀寫資料時,會先由快取程序檢查是否已經有資料,若有的話即直接傳回,如此便不用進入分散式儲存中讀寫,速度也可以顯著加快,這個機制稱為分散式快取(Distributed Cache)。

在 Google 以及開放原始碼的雲端平台中,最廣為使用的分散式快取平台是 memcached(Memory Cache Daemon),它是一個在伺服器或伺服器群組中建構分散式快取機制的工具與伺服程式,它可以跨越數個伺服器變成一個快取組,透過簡單易用的 API,應用程式可以在無需知道快取服務細節的情況下,即可運用 memcached 中所儲存的應用程式快取資料,當快取命中(hit)時,應用程式使用該資料的 I/O 會比不使用快取的情況下提升數倍。而微軟則是在 2008 年時,提出代號為 Velocity 的專案,開始實作微軟自己的分散式快取服務,目前這個服務已經內建於 Windows Server AppFabric 中作為 Cache Service,而公有雲的 Windows Azure 也於 PDC 2010 中宣布 Windows Azure Caching Service,作為 Windows Azure 雲端應用程式的快取服務。

目前 Windows Azure Cache Service 是 CTP 的階段,可以至 http://portal.appfabriclabs.com 中註冊使用,在 Management Portal 中,可以看到 Windows Azure 的 Cache Service 項目:

而微軟的 Windows Azure Cache Service API 與 Windows Server AppFabric Cache Service 相同,可直接沿用,API 所需的組態設定也可以由 Management Portal中 的 View Client Configuration 中取得,可直接選取後按 CTRL+C 複製出來:

而在應用程式開發的電腦上,必須要安裝有 Windows Azure SDK 2.0(目前最新的版本是 CTP February 2011),然後由專案中加入對 Microsoft.ApplicationServer.Caching.Client.dll 與 Microsoft.ApplicationServer.Caching.Core.dll 的參考,若是 Web 應用程式,則要再加上 Microsoft.Web.DistributedCache.dll 的參考,接著在程式碼中加入使用 Microsoft.ApplicationServer.Caching 命名空間的指令後,使用下列指令即可存取快取資料:

[C#]

// Cache client configured by settings in application configuration file. DataCacheFactory cacheFactory = new DataCacheFactory(); DataCache cache = cacheFactory.GetDefaultCache(); // Add and retrieve a test object from the default cache. defaultCache.Add("testkey", "testobject"); string strObject = (string)defaultCache.Get("testkey");

當然,如果你希望使用程式化的方式組態快取,可以參考下列程式碼:

[C#]

// Declare array for cache host. DataCacheServerEndpoint[] servers = new DataCacheServerEndpoint[1]; servers[0] = new DataCacheServerEndpoint("mytest.cache.int4.windows-test.net", 22233); // Setup DataCacheSecurity configuration. string strACSKey = "YWNzOmh0dHBzzzzvanJvdGhkb2N1bWVudGF0aW9udGVzdGluZy111WNoZS5hY2Nlc3Njb250cm9sLmlud" + "DMud2luZG93cy1pbnQubmV0L1dSQVB2MC45LyZvd25lciY0eDhHZTA5SlZTTUQ2VWIyWkNiaWlES1c0NXNzOFIxZjdWZVp0Y3lF" + "T2FFPSZodHRwOi8vSnJvdGhEb2N1bWVudGF0aW9uVGVzdGluZy5jYWNoZS5pbnQzLndpbmRvd3MtaW50Lm5ldA=="; var secureACSKey = new SecureString(); foreach (char a in strACSKey) { secureACSKey.AppendChar(a); } secureACSKey.MakeReadOnly(); DataCacheSecurity factorySecurity = new DataCacheSecurity(secureACSKey); // Setup the DataCacheFactory configuration. DataCacheFactoryConfiguration factoryConfig = new DataCacheFactoryConfiguration(); factoryConfig.Servers = servers; factoryConfig.SecurityProperties = factorySecurity; factoryConfig.IsRouting = false; // Create a configured DataCacheFactory object. DataCacheFactory cacheFactory = new DataCacheFactory(factoryConfig); // Get a cache client for the default cache. DataCache defaultCache = cacheFactory.GetDefaultCache(); // Add and retrieve a test object from the default cache. defaultCache.Add("testkey", "testobject"); string strObject = (string)defaultCache.Get("testkey");

對於 ASP.NET 應用程式來說,Windows Azure Cache Service 提供了不同程度的快取支援,像是我們可以設定將 Session 存到快取區(如下的 Web.config 設定):

[Web.config]

... <sessionState mode="Custom" customProvider="AppFabricCacheSessionStoreProvider"> <providers> <!-- specify the named cache for session data --> <add name="AppFabricCacheSessionStoreProvider" type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache" cacheName="default" applicationName="AzureStore" useBlobMode="false" /> </providers> </sessionState> ...

或是直接使用 Cache API:

[C#]

public class ProductsRepository : IProductRepository { ... public List<string> GetProducts() { List<string> products = null; DataCache dataCache = null; if (enableCache) { try { dataCache = CacheFactory.GetDefaultCache(); products = dataCache.Get("products") as List<string>; if (products != null) { products[0] = "(from cache)"; return products; } } catch (DataCacheException ex) { if (ex.ErrorCode != DataCacheErrorCode.RetryLater) { throw; } // ignore temporary failures } } NorthwindEntities context = new NorthwindEntities(); var query = from product in context.Products select product.ProductName; products = query.ToList(); return products; } }

都可以達到存取 Cache Service 的效果。

NOTE

若是對 Windows Azure 有興趣,可至 MSDN Virtual Lab 中,可以找到 Building Windows Azure Applications with the Caching Service 的 Hands-on Lab。