次の方法で共有


キャッシュの統合

ASP.NET でのカスタム OutputCache プロバイダーの作成と使用

Brandon Satrom

コード サンプルのダウンロード

Web 開発者であれば、これまで ASP.NET が提供する出力キャッシュ機能を使用した経験がおありかもしれません。Microsoft .NET Framework の最初のバージョンで導入された ASP.NET の出力キャッシュを使用すると、ページまたはコントローラーを再実行しないで、要求されたコンテンツをキャッシュから取得することで、サイトの訪問者にコンテンツを提供する処理のパフォーマンスを改善できます。これにより、アプリケーションは、頻繁に更新されないデータや一定の期間が過ぎると無効になり得るデータを返すときに、処理コストの高いデータベース呼び出しの回数を少なくすることができます。

ASP.NET の出力キャッシュはメモリ内の記憶域メカニズムを使用し、.NET Framework 4 がリリースされるまでは、既定のキャッシュを独自の実装によってオーバーライドしたり置き換えたりすることはできませんでした。.NET Framework 4 からは新しい OutputCacheProvider 型により、ASP.NET のページ出力のキャッシュに独自のメカニズムを実装できるようになりました。

この記事では、このようなカスタム メカニズムを 2 つ紹介します。1 つ目は、よく使われるドキュメント指向データベースの MongoDB を使用して、簡単な ASP.NET MVC アプリケーションでの出力キャッシュ処理を容易にする独自のプロバイダーを作成します。次に、同じアプリケーションを使用して、作成したカスタム プロバイダーを、Windows Azure AppFabric の機能を利用するよう、簡単に置き換えます。具体的には、Windows Azure インフラストラクチャーを利用してクラウドでの分散型メモリ内キャッシュを実現する、新しい DistributedCache プロバイダーに置き換えます。

ASP.NET の出力キャッシュ

ASP.NET Web フォーム アプリケーションでは、ASP.NET ページまたはユーザー コントロールに OutputCache ページ ディレクティブを追加することで、出力キャッシュを構成できます。

<%@ OutputCache Duration="60" Location="Any" VaryByParam="name" %>

ASP.NET MVC アプリケーションの場合、出力キャッシュは、ASP.NET MVC に付属のアクション フィルターを使用することで実現できます。また、このアクション フィルターは、すべてのコントローラー アクションの属性として利用できます。

[OutputCache(Duration=60, VaryByParam="none")]

ASP.NET MVC 1 と MVC 2 のアプリケーションには "Duration" と "VaryByParam" が必須です (ASP.NET MVC 3 では VaryByParam は省略可能)。また、ASP.NET MVC 1 と MVC 2 には、コンテンツのキャッシュ方法の制御を可能にするもの (いくつかの VaryByX パラメーター)、コンテンツのキャッシュ先の制御を可能にするもの (Location)、キャッシュの無効化の依存関係の設定を可能にするもの (SqlDependency) など、他にも属性やパラメーターがいくつかあります。

従来の出力キャッシュでは、アプリケーションへの実装に必要なものは上記のみです。OutputCache 型は HttpModule の 1 つで、アプリケーション起動時に実行され、ページ ディレクティブまたはアクション フィルターを検出した場合に処理を行います。問題のページまたはコントローラーが初めて要求された時点で、ASP.NET は結果のコンテンツ (HTML、CSS、JavaScript ファイルなど) を取得し、各アイテムの有効期限と各アイテムを識別するためのキーを組み合わせて、メモリ内キャッシュに保存します。有効期限は Duration プロパティによって決まり、キーはページへのパスと必要な VaryBy 値 (たとえば、VaryByParam プロパティを指定している場合はクエリ文字列またはパラメーター) によって決まります。したがって、コントローラーのアクションは、次のように定義することをお勧めします。

[OutputCache(Duration=20, VaryByParam="vendorState")]
Public ActionResult GetVendorList(string vendorState)
{
  // Action logic here.
}

この場合、ある州が要求されると、その vendorState (州) に対する結果の HTML ビュー (テキサス州のビュー、ワシントン州のビューなど) のインスタンスが、ASP.NET によってキャッシュされます。各インスタンスの格納に使用されるキーは、この場合、パスと該当する vendorState とを組み合わせたものです。

一方、VaryByParam プロパティを "none" に設定すると、GetVendorList が初めて実行されたときの結果がキャッシュされ、その後のすべての要求では、GetVendorList に渡した vendorState パラメーターがどのような値であっても、キャッシュされた結果と同じコンテンツが返されます。VaryByParam 値を指定していなければ、このインスタンスの格納に使用されるキーは、パスだけで構成されます。このプロセスを簡単に図示します (図 1 参照)。

image: The ASP.NET Output Caching Process

図 1 ASP.NET の出力キャッシュ プロセス

出力キャッシュでは、Duration パラメーターを使用してキャッシュ内のアイテムの有効期間を制御したり、いくつかの VaryBy パラメーター (VaryByParam、VaryByHeader、VaryByCustom、VaryByControl、VaryByContentEncoding) を使用してキャッシュするアイテムの詳細度を制御したりするだけでなく、キャッシュするコンテンツの格納先 (クライアント、サーバー、またはダウンストリーム プロキシ) も制御できます。また、ASP.NET 2.0 で導入された SqlDependency 属性を使用すると、ページまたはコントロールが依存するデータベース テーブルを指定できるため、有効期間が終了した場合だけでなく、基盤のソース データが更新された場合も、キャッシュされているアイテムを無効にできます。

.NET Framework 2.0 および 3.0 では、既定のキャッシュ プロバイダーにいくつかの機能強化が施されていますが、プロバイダー自体は同じです。つまり、プロバイダー自体はメモリ内のストアで、拡張ポイントやカスタム実装の手段はありません。このメモリ内キャッシュは、ほとんどの場合、まったく問題なく利用できますが、ときどき、サーバー リソースの使用率が極限に達し、利用可能なメモリが少なくなることで、サイトのパフォーマンスの低下を招く場合があります。さらに、既定のキャッシュ プロバイダー メカニズムでは、メモリ量が少なくなると、指定されている有効期間に関係なく、キャッシュ済みのリソースが自動的に破棄されます。このため、キャッシュ済みリソースが管理される方法については、開発者はほとんど制御できませんでした。

ASP.NET の拡張可能な出力キャッシュ

.NET Framework 4 のリリースでは、開発者がカスタム出力キャッシュ プロバイダーを作成し、新規または既存のアプリケーションとその構成を少し変更するだけで、作成したプロバイダーをアプリケーションに組み込むことができる新機能が導入されました。カスタム プロバイダーでは、キャッシュ情報の格納メカニズムに、ローカル ディスク、リレーショナルおよび非リレーショナル データベース、クラウド、さらには Windows Server AppFabric で提供されているような分散キャッシュ エンジンなど、任意のメカニズムを自由に使用できます。また、同じアプリケーションのページでも、各ページに合わせて複数のプロバイダーを使用することもできます。

カスタム出力キャッシュ プロバイダーを作成するのは簡単で、新しい System.Web.Caching.OutputCacheProvider 抽象クラスから新しい派生クラスを作成し、ASP.NET によるキャッシュ アイテムの操作に必要な 4 つのメソッドをオーバーライドするだけです。OutputCacheProvider クラスの .NET Framework での定義を次に示します (詳細については、bit.ly/fozTLc を参照してください)。

public abstract class OutputCacheProvider : ProviderBase
{
  public abstract object Get(string key);
  public abstract object Add(string key, object entry, DateTime utcExpiry);
  public abstract void Set(string key, object entry, DateTime utcExpiry);
  public abstract void Remove(string key);
}

これらの 4 つのメソッドを実装したら、後は新しいプロバイダーを web.config に追加し、これを既定のプロバイダーに指定して、OutputCache ディレクティブまたは属性をアプリケーションに追加するだけです。その手順については、MongoDB という名前のドキュメント データベースを使用するカスタム キャッシュ プロバイダーを作成しながら、詳しく説明します。しかし、まず、カスタム プロバイダーの作成に使用するツールの背景を少し紹介しておくと役に立つでしょう。

NoSQL、ドキュメント データベース、および MongoDB

過去数十年にもわたり、アプリケーションの記憶域メカニズムには、データとリレーションシップをテーブルに格納するリレーショナル データベース管理システム (RDBMS) が好んで使用されてきました。RDBMS の例としては SQL Server や Oracle があり、現在一般に使用されている商用およびオープン ソース データベースの大半は RDBMS です。

ただし、記憶域を必要とするすべての問題が、同じトランザクション パターンに当てはまるわけではありません。90 年代後半に、インターネットが普及し多くのサイトが大量のデータを扱うようになると、データ処理の多い特定のアプリケーションについては、リレーショナル モデルでは理想的なパフォーマンスが得られないことが明らかになりました。たとえば、大量のドキュメントのインデックスを作成する場合、トラフィックの多いサイトで Web ページを返す場合、メディアをコンシューマーにストリーミングする場合などです。

多くの企業が、NoSQL データベースを利用して、増加する記憶域ニーズに対応しました。NoSQL は、SQL インターフェイス、固定スキーマ、または定義済みリレーションシップを公開しない、軽量データベースの一種です。NoSQL データベースは、Google Inc. (BigTable)、Amazon.com Inc. (Dynamo)、Facebook (受信ボックスの検索用に 50 TB の記憶域を用意している) などの企業によって大々的に使用されており、人気も使用率も着実に伸びています。

すべての RDBMS の放棄を声高に求める手段として、NoSQL という語が使用される場合もありますが、RDBMS と NoSQL の両方を使用することで得られる価値を強調する声にも目を向ける必要があります。NoSQL データベースは、RDBMS に替わるシステムではなく、RDBMS では解決できない類の問題を解決するシステムであると考えられていました。造詣が深い開発者であれば、これら 2 つのシステムを理解して、適切に使い分け、ときには、同じアプリケーションで両方の記憶域を併用するでしょう。

NoSQL データベースが適している状況の 1 つが、出力キャッシュです。NoSQL データベースは、一時的なデータの操作に最適であり、ASP.NET アプリケーションのキャッシュ ページは間違いなくこれに該当します。よく使用される NoSQL の 1 つが MongoDB (mongodb.org、英語) です。MongoDB は、ドキュメント指向の NoSQL データベースで、Shutterfly、Foursquare、The New York Times などで使用されています。MongoDB は C++ で書かれた正真正銘のオープン ソース データベースで、C# も含めほぼすべての主要プログラミング言語のドライバーが付属しています。ここでは、カスタム出力キャッシュ プロバイダーの記憶域メカニズムに MongoDB を使用します。

MongoDB を使用してカスタム OutputCacheProvider を作成する

作業を始めるには、mongodb.org (英語) にアクセスして、MongoDBをダウンロードして、インストールします。mongodb.org/display/DOCS/Quickstart (英語) のドキュメントには、MongoDB を Windows、Mac OS X、および Unix にインストールするために必要な情報がすべて記載されています。MongoDB をダウンロードし、シェルを使用してテストを実施したら、インストール ディレクトリから次のコマンドを使用して MongoDB データベースをサービスとしてインストールすることをお勧めします (必ず管理者として cmd.exe を実行してください)。

C:\Tools\MongoDB\bin>mongod.exe --logpath C:\Tools\MongoDB\Logs --directoryperdb --install

MongoDB がコンピューターにサービスとしてインストールされ、すべての MongoDB データベースの既定のディレクトリには \Data\db が使用されます。--diretoryperdb オプションを付け、MongoDB によって作成するデータベースごとにルート ディレクトリが作成されるようにしています。

上記のコマンドを実行したら、次のコマンドを入力して、サービスを開始します。

net start MongoDB

実行中になったら、.NET で MongoDB を使用できるように、ドライバー ライブラリをインストールする必要があります。選択肢はいくつかありますが、ここでは Sam Corder 氏が開発した mongodb-csharp (github.com/samus/mongodb-csharp、英語) を使用します。

MongoDB をインストールし、.NET アプリケーションで使用できるドライバーも用意したので、カスタム出力キャッシュ プロバイダーを作成しましょう。そのため、ここでは DocumentCache という新しいクラス ライブラリを作成し、DocumentDatabaseOutputCacheProvider と CacheItem という 2 つのクラスを追加します。

前者はプロバイダーで、OutputCacheProvider 抽象クラスのサブクラスになるパブリック クラスです。では、最初の実装を図 2 に示します。

図 2 最初の OutputCacheProvider クラス

public class DocumentDatabaseOutputCacheProvider : OutputCacheProvider  
{ 
  readonly Mongo _mongo; 
  readonly IMongoCollection<CacheItem> _cacheItems; 
         
  public override object Get(string key) 
  { 
    return null; 
  } 
  
  public override object Add(string key, object entry, DateTime utcExpiry) 
  { 
    return null; 
  } 
  
  public override void Set(string key, object entry, DateTime utcExpiry) 
  { 
    return; 
  } 
  
  public override void Remove(string key) 
  { 
    return; 
  } 
}

図 2 の 2 つ目のプライベート変数は、このプロジェクトに作成する必要があるもう 1 つのクラス CacheItem を参照していることに注意してください。CacheItem は、ASP.NET とデータベースの両方を操作するために出力キャッシュ プロバイダーが必要とする、関連詳細情報を保持するために用意します。したがって、CacheItem は次のように内部クラスとして定義します。

[Serializable] 
internal class CacheItem 
{ 
  public string Id { get; set; } 
  public byte[] Item { get; set; } 
  public DateTime Expiration { get; set; } 
}

Id は、ASP.NET によって渡されたキーにマップします。このキーは、パスとページ ディレクティブまたはアクション属性で定義された VaryBy 条件を組み合わせたものです。Expiration フィールドは Duration パラメーターに対応しています。Item プロパティはキャッシュされるアイテムです。

まず、DocumentDatabaseOutputCacheProvider クラスのコンストラクターを構成することで、プロバイダーを実装します。ASP.NET はアプリケーション実行中の最初から最後まで、プロバイダーのインスタンスを 1 つだけ保持することがわかっているため、コンストラクター内で次のような構成作業を実行できます。

readonly Mongo _mongo; 
readonly IMongoCollection<CacheItem> _cacheItems; 
         
public DocumentDatabaseOutputCacheProvider() 
{ 
  _mongo = new Mongo(); 
  _mongo.Connect(); 
             
  var store = _mongo.GetDatabase("OutputCacheDB"); 
  _cacheItems = store.GetCollection<CacheItem>(); 
}

このコンストラクターは、Mongo 型の新しいインスタンスを作成し、既定の場所 (localhost) を使用してサーバーに接続します。その後、MongoDB に OutputCacheDB データベースと、CacheItem 型の IMongoCollection 返すように要求します。MongoDB はスキーマのないデータベースであるため、その場でのデータベース作成がサポートされます。まず、_mongo.GetDatabase("OutputCacheDB") を呼び出すと新しいデータベースのインスタンスが返されます。このデータベースは最初の挿入が実行されたディスクに作成されます。

今度は、Add メソッドを実装します (図 3 参照)。

図 3 Add メソッドの実装

public override object Add(string key, object entry, DateTime utcExpiry) 
{ 
  key = MD5(key); 
  var item = _cacheItems.FindOne(new { _id = key }); 
  if (item != null) { 
    if (item.Expiration.ToUniversalTime() <= DateTime.UtcNow) { 
      _cacheItems.Remove(item); 
    } else { 
      return Deserialize(item.Item); 
    } 
  } 
  
  _cacheItems.Insert(new CacheItem 
  { 
    Id = key, 
    Item = Serialize(entry), 
    Expiration = utcExpiry 
  }); 
  
  return entry
}

各メソッドで最初に実行するのは、渡されたキーに対する MD5 メソッドの呼び出しです。このメソッド (説明を簡単にするため省略していますが、オンラインのソース コードのダウンロードには含まれています) は、ASP.NET から渡されたキーを基にデータベースで使用しやすい MD5 ハッシュを生成します。次に、IMongoCollection<CacheItem> 型の _cacheItems を呼び出し、基盤のデータベースに問題のキーを照会します。匿名型 (new { _id = key}) を FindOne メソッドに渡していることに注意してください。MongoDB へのクエリは、主に、データベース内の照合対象ドキュメントの 1 つ以上のフィールドを指定しているセレクター オブジェクトまたはテンプレート ドキュメントによって行われます。_id は、MongoDB がドキュメントの格納に使用するキーで、(ここで使用しているドライバーの慣例では) このプロパティは自動的に CacheItem クラスの Id プロパティにマップされます。したがって、新しいキャッシュ アイテムを保存すると、図 3 の _cacheItems.Insert メソッドからわかるように、Id プロパティを使用してキーが割り当てられます。MongoDB はこのキーを使用して、レコードの _id フィールドに値を設定します。MongoDB はキーと値のストアであるため、各 CacheItem オブジェクトは、次のようなバイナリ シリアル化された JSON を使用して格納されます。

{ "_id" : ObjectId(Id), "CacheItem": new CacheItem { Id = key, Item = entry, Expiration = utcExpiry } }

渡されたものと同じキーの CacheItem が見つかると、UTC 現在時刻に対してそのアイテムの有効期限を確認します。アイテムが有効期限内であれば、プライベート メソッド (オンラインのソース コードに含めています) を使用してこれをバイナリ シリアル化解除し、既存のアイテムを返します。期限切れであれば、新しいアイテムをストアに挿入して、バイナリ シリアル化し、渡されたエントリを返します。

キャッシュへのアイテムの追加操作を実装したら、キーを基にキャッシュされたアイテムを検索して返す (または、該当アイテムが見つからない場合は null を返す) Get メソッドを追加します (図 4 参照)。

図 4 Get メソッドの実装

public override object Get(string key) 
{ 
  key = MD5(key);  
  var cacheItem = _cacheItems.FindOne(new { _id = key }); 
  
  if (cacheItem != null) { 
    if (cacheItem.Expiration.ToUniversalTime() <= DateTime.UtcNow) { 
       _cacheItems.Remove(cacheItem); 
      } else { 
        return Deserialize(cacheItem.Item); 
    } 
  } 
    
  return null; 
}

Add メソッドと同様に、Get メソッドもデータベースに目的のアイテムが存在する場合はアイテムの有効期限を確認し、期限切れの場合は、このアイテムを削除して null を返します。アイテムが存在し、有効期限内であれば、そのアイテムが返されます。

今度は、次のように Remove メソッドを実装します。Remove メソッドはキーを受け取り、そのキーに一致するアイテムをデータベースから削除します。

public override void Remove(string key) 
{ 
  key = MD5(key); 
  _cacheItems.Remove(new { _id = key }); 
}

まだ実装していませんが、ドライバーがデータベースの取得に使用するコードと同様に、データベース内にないアイテムの削除を試みると、MongoDB により警告が返されます。その場合、何の処理も行いません。

ここで使用している抽象基本クラスに従うと、機能するカスタム出力キャッシュ プロバイダーを作成するために実装が必要なメソッドがまだ 1 つ残っています。つまり、Set メソッドを実装する必要があります。図 5 のように Set メソッドを実装します。

図 5 Set メソッドの実装

public override void Set(string key, object entry, DateTime utcExpiry)
{
  key = MD5(key); 
  var item = _cacheItems.FindOne(new { _id = key }); 
  
  if (item != null) 
  { 
    item.Item = Serialize(entry); 
    item.Expiration = utcExpiry; 
    _cacheItems.Save(item); 
  } 
  else 
  { 
    _cacheItems.Insert(new CacheItem 
    { 
      Id = key, 
      Item = Serialize(entry), 
      Expiration = utcExpiry 
    }); 
  }
}

一見すると、Add メソッドと Set メソッドは同じに見えますが、それぞれの意図する実装には重要な違いがあります。OutputCacheProvider クラスについての MSDN ドキュメント (bit.ly/fozTLc) によると、カスタム プロバイダーの Add メソッドでは、指定されたキーに一致する値をキャッシュ内で検索し、該当する値が存在する場合は、保存されているアイテムを返します。目的のアイテムが存在しない場合は、Add によりそのアイテムが挿入されます。

一方、Set メソッドでは、常にキャッシュに値が追加されます。つまり、目的のアイテムが存在しない場合は挿入され、存在する場合は上書きされます。図 3 の Add メソッドと図 5 の Set メソッドのコードを見るとわかるように、この 2 つのメソッドは指定された通りに動作しています。

これで 4 つのメソッドを実装できたので、プロバイダーを実行できるようになりました。

ASP.NET MVC で MongoDB OutputCacheProvider を使用する

カスタム プロバイダーをコンパイルしたら、数行の構成を記述するだけで、任意の ASP.NET アプリケーションにプロバイダーを追加できます。プロバイダーを含むアセンブリへの参照を追加したら、web.config ファイルの <system.web> セクションに次のテキストを追加します。

<caching> 
  <outputCache defaultProvider="DocumentDBCache"> 
    <providers> 
      <add name="DocumentDBCache" 
       type="DocumentCache.DocumentDatabaseOutputCacheProvider, DocumentCache" /> 
    </providers> 
  </outputCache>
</caching>

<providers> 要素は、アプリケーションに追加するすべてのカスタム プロバイダーを定義し、各プロバイダーの名前と型を定義します。1 つのアプリケーションに複数のカスタム プロバイダーを追加できるため、上記のコード スニペットのように、defaultProvider 属性も指定することをお勧めします。

この記事のサンプル アプリケーションは、CustomersController を設定している単純な ASP.NET MVC サイトです。このコントローラーには、この例の企業にとっての上客の一覧を返す TopCustomers というアクションがあります。この情報は複雑な計算と SQL Server のいくつかのデータベース クエリを実行した結果得られたもので、1 時間に 1 回しか更新されません。したがって、キャッシュを利用する候補として理想的なデータです。そこで、次のように OutputCache 属性をアクションに追加します。

[OutputCache(Duration = 3600, VaryByParam = "none")] 
public ActionResult TopCustomers() 
{ 
  var topCustomers = _repository.GetTopCustomers(); 
  return View(topCustomers); 
}

この時点で、サイトを実行し、TopCustomers ページに移動すると、カスタム プロバイダーの処理が開始されます。最初に Get メソッドが呼び出されますが、このページはまだキャッシュされていないので、何も返されません。次に、コントローラーのアクションが実行され、TopCustomers ビューが返されます ( 図 6).参照。

image: The Cached TopCustomers View

図 6 キャッシュされている TopCustomers のビュー

次に、ASP.NET によってカスタムのキャッシュ プロバイダーが呼び出され、Set メソッドが実行されて、アイテムがキャッシュされます。有効期間を 3,600 秒 (60 分) に設定し、コントローラー アクションを再実行するのではなく、この期間に発生した後続のすべての要求に、Get メソッドによって返されるキャッシュ済みアイテムが使用されるようにします。基盤のデータが変更された場合、有効期間内での初回の実行時に更新内容が反映され、この新しい情報がキャッシュされて 1 時間有効になります。MongoDB の動作を実際に確認する場合は、2、3 とおりの方法があります。ブラウザーを開き、http://localhost:28107/ に移動すると、ログと最近実行したクエリおよびデータベースに関する統計情報が表示されます。または、MongoDB のインストール先の bin ディレクトリから mongo.exe を実行し、Mongo Shell を使用してデータベースにクエリを送ります。これらのツールの使用方法の詳細については、mongodb.org (英語) を参照してください。   

DistributedCache プロバイダーを使用する

では、ここまで説明したことがどれも実行したい内容ではなかったとしたらどうでしょう。おそらく、別のキャッシュ メカニズムを利用することを考えますが、独自のメカニズムを考案する時間も余裕もなければどうすればよいでしょう。さいわいにも、拡張可能な出力キャッシュの導入以来、代わりのメカニズム (商用、オープン ソース、マイクロソフト製) が多数既に提供されているか、開発中です。その一例が、クラウドベースの分散型メモリ内キャッシュの DistributedCache プロバイダーで、現在、Windows Azure AppFabric の一部として提供されています。既にクラウドベースのアプリケーションを作成しているのであれば、Windows Azure AppFabric キャッシュを利用すると、このようなアプリケーションのデータ アクセスの速度を向上でき、キャッシュがクラウド サービスとして実現されるため、設定が簡潔で、管理オーバーヘッドがかかりません。

この記事の執筆時点では、AppFabric キャッシュは 10 月にリリースされた Windows Azure AppFabric CTP 版に含まれているため、アクティブな Windows Azure アカウントがなくてもキャッシュ機能を利用できます。ただし、MSDN 会員の方であれば、Windows Azure の特典を windows.azure.com (英語) からアクティブにされることを強くお勧めします。portal.appfabriclabs.com (英語) にアクセスし、CTP 版の機能を使用するためのアカウントを作成してください。

ラボ アカウントを作成したら、[Add Service Namespace] (サービスの名前空間の追加) リンクをクリックして、AppFabric サービスを有効にします (図 7 参照)。

image: Windows Azure AppFabric Labs Summary Page

図 7 Windows Azure AppFabric のラボの概要ページ

サービスの名前空間を設定したら、[Cache] (キャッシュ) リンクをクリックして、キャッシュのセクションに表示されるサービスの URL と認証トークンをメモします (図 8 参照)。この情報は、DistributedCache プロバイダーを使用するようにアプリケーションを構成する際に必要です。

image: AppFabric Labs Cache Settings Page

図 8 AppFabric ラボの [Cache Settings] (キャッシュ設定) ページ

次は、Windows Azure AppFabric SDK をダウンロードし、インストールする必要があります (ポータルの [Cache] (キャッシュ) ページ上のダウンロード リンクをクリックします)。インストールが完了したら、Windows Azure AppFabric キャッシュをアプリケーション向けに構成できます。

SDK のインストール時にコンピューターに配置されたアセンブリに、いくつかの参照を追加する必要があります。カスタム ドキュメント データベース キャッシュに使用したものと同じ ASP.NET MVC アプリケーションを使用して、SDK のインストール先 (既定では C:\Program Files*\Windows Azure AppFabric SDK\V2.0\Assemblies\Cache) に移動し、そこにある各アセンブリに参照を追加します。

参照を追加したら、web.config を開いて、既存の構成セクションを変更しないで、次の <configSections> エントリを追加します。

<configSections> 
  <section name="dataCacheClient"  
     type="Microsoft.ApplicationServer.Caching.DataCacheClientSection, 
           Microsoft.ApplicationServer.Caching.Core"  
     allowLocation="true" allowDefinition="Everywhere"/>
</configSections>

今度は、次のように <dataCacheClient> セクションを作成し、<host> の name、cachePort、および <messageSecurity> の authorizationInfo プロパティを実際のポータル アカウントの情報に置き換えます。

<dataCacheClient deployment="Simple"> 
  <hosts> 
    <host name="yournamespace.cache.appfabriclabs.com" cachePort="your port" /> 
  </hosts> 
  <securityProperties mode="Message"> 
    <messageSecurity authorizationInfo="your authentication token"> 
    </messageSecurity> 
  </securityProperties> 
</dataCacheClient>

次に、<system.web> 以下の <caching> セクションを探して、カスタム プロバイダー用に作成したエントリの後に、次のプロバイダー エントリを追加します。

<add name="DistributedCache" 
     type="Microsoft.Web.DistributedCache.DistributedCacheOutputCacheProvider, 
      Microsoft.Web.DistributedCache" 
     cacheName="default" />

最後に、<outputCache> 要素の defaultProvider 属性を "DistributedCache" に変更します。DistributedCacheOutputCacheProvider は、この記事の MongoDB 実装と同様に、OutputCacheProvider 抽象クラスのサブクラスです。では、アプリケーションをビルドして実行し、Top Customers ページに移動しましょう。顧客の一覧がキャッシュされている状態で顧客を追加して見てください。この記事の MongoDB 実装と同様に、顧客の一覧は指定がない限りキャッシュされた状態のままです。

まとめ

この記事では、ASP.NET 出力キャッシュ、既定のメモリ内キャッシュの従来の使い方、および .NET Framework 4 の OutputCacheProvider 抽象クラスを使用して提供される新しい拡張可能なキャッシュ機能について説明しました。また、NoSQL とドキュメント データベース、およびキャッシュ済み出力のような一時データの操作に、このようなシステムが理想的である理由を説明しました。MongoDB を使用して、サンプル出力キャッシュを作成し、このキャッシュを ASP.NET MVC アプリケーション内で使用しました。最後に、出力キャッシュをクラウドに移植し、少しの設定と構成だけで、まったくコードの変更をせずに、アプリケーション内の出力キャッシュ メカニズムを交換できました。

拡張可能な出力キャッシュは、ASP.NET 4 のさまざまな素晴らしい新機能の 1 つにすぎません。拡張可能な出力キャッシュ (およびこの機能と連携して利用できるテクノロジ) について、この記事でお伝えした情報がお役に立っていればさいわいです。MongoDB の詳細については、mongodb.org (英語) を参照してください。Windows Azure AppFabric の詳細については、portal.appfabriclabs.com を参照してください。

Brandon Satrom は、テキサス州オースティンでマイクロソフトの開発者エバンジェリストとして活躍しています。彼のブログは userinexperience.com (英語) です。Twitter のアカウントは @BrandonSatrom (英語) です。

この記事のレビューに協力してくれた技術スタッフの Brian H. PrinceClark Sell に心より感謝いたします。