Windows Azure:インメモリ分散キャッシュ

ごく最近、MicrosoftはWindows Azureプラットフォーム用の大規模なサービスパックを発表しました。 革新のリストには、待望のWindows Azureキャッシングの更新が含まれていました。 以前は、開発者は分散キャッシュシステムで作業する際にいくつかの困難に直面していました-キャッシュの動作は非常に遅いです。 Windows Azureはキャッシュデータを別のサーバーに保存したため、データサンプルを要求するのに約30〜100ミリ秒かかりました。これは、データアクセスを高速化するシステムでは許可されません。

それでは、キャッシングシステムの何が変わったのでしょうか?

マイクロソフトは、競合他社に追いつくことを決定し、インメモリキャッシュのサポートを追加しました。 現在、データは別のサーバーではなく、サーバーのRAMに保存されているため、データへのアクセスは即座に発生します。 例としてASP.NET MVC 3(C#)を使用して、新しいキャッシュを実装し、古いキャッシュと作業速度を比較してみましょう。



キャッシングプロバイダー


キャッシュにアクセスするには、プロバイダーが必要です。 プロバイダーを実装するには、必要なメソッドを使用してプロバイダーのインターフェイスを作成します。

public interface ICacheProvider { void RemoveFromCache(string key); T GetFromMethod<T>(string cacheKey, TimeSpan cacheDuration, Func<T> method); T GetFromMethod<T>(string cacheKey, Func<T> method); }
      
      





最初の方法は、明らかに、キーによってキャッシュからオブジェクトを削除し、残りはキーと期間が設定されたデータを受け取ります(キャッシュがない場合は追加します)。



次のステップは、プロバイダー自体を実装することです。 Windows Azure SDK 1.7のインストールプロセスについては説明していません。開発者はWindows Azureでの開発に必要なすべてのライブラリとコンポーネントを持っていることが理解されます



プロバイダーを実装する際に考慮すべきいくつかの重要な点に注意してください。



プロバイダー自体は次のようになります。



 public class AzureCacheProvider : ICacheProvider { //        private readonly string _prefix = StaticHelper.GetCurrentVersion(); private readonly object _locker = new object(); private readonly DataCache _cache; public AzureCacheProvider() { lock (_locker) { { var factory = new DataCacheFactory(); _cache = factory.GetDefaultCache(); } } } private void RemoveFromCache(string key, DataCache cache) { lock (_locker) { cache.Remove(_prefix + key); HttpContext.Current.Items.Remove(_prefix + key); } } private T GetFromCache<T>(string key, TimeSpan expiration, Func<T> method, DataCache cache) { object cacheItem = HttpContext.Current.Items[_prefix + key]; if (cacheItem == null) { cacheItem = cache.Get(_prefix + key); if (cacheItem != null) HttpContext.Current.Items[_prefix + key] = cacheItem; } if (cacheItem == null) { lock (_locker) { cacheItem = cache.Get(_prefix + key); if (cacheItem == null) { cacheItem = method(); if (cacheItem != null) { HttpContext.Current.Items[_prefix + key] = cacheItem; cache.Put(_prefix + key, cacheItem, expiration); } } } } return (T)cacheItem; } public void RemoveFromCache(string key) { RemoveFromCache(key, _cache); } public T GetFromMethod<T>(string cacheKey, TimeSpan expirationSeconds, Func<T> method) { return GetFromCache(cacheKey, expirationSeconds, method, _cache); } public T GetFromMethod<T>(string cacheKey, Func<T> method) { return GetFromMethod(cacheKey, TimeSpan.FromMinutes(15), method); } }
      
      







ここでHttpContext.Current.Items



は、データへのアクセスが繰り返される場合に、キャッシュからの現在の要求で既に受信したオブジェクトをメモリに格納するために使用されます。



ロール構成


プロバイダーを作成した後、キャッシュを構成する必要があります。 SDK 1.7では、ロールプロパティに新しい[キャッシュ]タブが追加されました。



画像



このタブで、キャッシュサポートを有効にし(キャッシュを有効にする)、データに割り当てるメモリの量を設定します(例:Co-located Role:Cache Size 30%)



Web.config


最終的な準備は、Web.configに新しいセクションを追加することです。 ファイルの先頭にconfigSections



セクションがない場合、追加する必要があります。 次に、次のコードを内部に配置します。



 <section name="dataCacheClients" type="Microsoft.ApplicationServer.Caching.DataCacheClientsSection, Microsoft.ApplicationServer.Caching.Core" allowLocation="true" allowDefinition="Everywhere"/>
      
      





Web.configの最後に、 dataCacheClients



セクションの説明を追加します。



 <dataCacheClients> <tracing sinkType="DiagnosticSink" traceLevel="Error" /> <dataCacheClient name="default"> <autoDiscover isEnabled="true" identifier="   Web-,       " /> </dataCacheClient> </dataCacheClients>
      
      





これで、Windows Azureキャッシングの構成が完了しました。 ヘルスチェックに移りましょう。



キャッシュテスト



キャッシュをテストするには、現在の時刻をキャッシュする簡単なページを作成します。



 <h1>Cache test</h1> Before: <%=DateTime.Now.Millisecond%> ms<br/> <%=Facade.Instance.Cache.GetFromMethod("currentTime", () => DateTime.Now)%><br/> After: <%=DateTime.Now.Millisecond%> ms<br/> <%using(Html.BeginForm("ClearCache","Admin"))%> <%{%> <input type="submit" value="Clear Cache"/> <%}%>
      
      





上記のコードのFacade.Instance.Cache



は、IoCを使用して取得したAzureCacheProvider



インスタンスです。

ClearCache



アクションはClearCache



にシンプルに見えます。



 public ActionResult ClearCache() { Facade.Instance.Cache.RemoveFromCache("currentTime"); return View("admin"); }
      
      





結果



プロジェクトをコンパイルし、クラウドでページを起動すると、次の結果が表示されます。



Cache test

Before: 553 ms

6/10/2012 11:09:40 AM

After: 569 ms








最初にページを開くと、キャッシュにエントリが追加されます。この例では約16ミリ秒かかります。 次回ページが更新されると、結果は次のようになります。



Cache test

Before: 508 ms

6/10/2012 11:09:40 AM

After: 508 ms








新しいインメモリ分散キャッシュからデータを取得するのにかかる時間は1ミリ秒未満です。 速度面では、このキャッシュはInProcキャッシュに劣りません。



以前はどうでしたか?



以前の状態を確認するには、SDKをバージョン1.6にロールバックし、Web.configに小さな変更を加える必要があります。 dataCacheClients



セクションを次のように置き換えます。



 <dataCacheClients> <dataCacheClient name="default"> <hosts> <host name="[ ID].cache.windows.net" cachePort="22233" /> </hosts> <securityProperties mode="Message"> <messageSecurity authorizationInfo="[ ]"></messageSecurity> </securityProperties> </dataCacheClient> </dataCacheClients>
      
      





プロジェクトをコンパイルしてテストページを開くと、次の結果が表示されます。



Cache test

Before: 521 ms

6/10/2012 11:09:40 AM

After: 550 ms








つまり キャッシュへのエントリの追加およびページの更新後の29ミリ秒:



Cache test

Before: 501 ms

6/10/2012 11:09:40 AM

After: 533 ms








キャッシュエントリの取得に32ミリ秒。



まとめ



MicrosoftがWindows Azureの主な問題の1つである分散キャッシュの問題を解決した最新のイノベーション。 これで、アプリケーションパフォーマンスの低下を恐れずに分散キャッシュを使用でき、Azureクラウド内でこれに他のツールを使用したユーザーは、Windows Azure APIが提供する機能に戻ることができます。



All Articles