最新の Redis Cache については「Azure Redis Cache の使用 (.NET, PHP, Node.js)」に記載しました。(以降は、古い記事です)
環境 : Visual Studio 2010 (.NET Framework 4), Windows Server AppFabric
Windows Server AppFabric 入門
- Host Services (ホスティングサービス)
- Cache Services (キャッシュサービス)
関連ナンバー
- Windows Server AppFabric Cache v1.0
- Cache 機能一覧
- Windows Azure Shared Cache
- Windows Server AppFabric Cache v1.1 (新機能紹介)
- Windows Azure Role-based Cache
- New Windows Azure Cache (留意点)
こんにちは。
Tech Ed 2010 の予習として、コードネーム Velocity と呼ばれていた Windows Server AppFabric のキャッシュサービス (Cache Services) の超入門を記載します。(冗長な余談はいっさい書きません。。。)
なお、ホスティングサービス (コードネーム Dublin) のほうは、以前このブログで記載していますので、上記のリンクを参考にしてください。(今回、このホスティングサービスの内容も RTM 用に書き換えました。)
キャッシュサービス (Velocity) とは何者か?
まず、このキャッシュ サービスって何でしょうか?
これは、いわゆるインメモリ データの分散キャッシュ技術と呼ばれるもので、アプリケーションの中で扱うインメモリ データに対して莫大なスケーラビリティが必要とされるようなケースや、データベースへの負荷を減らしながらデータ アクセスの高速化をおこなうようなケースで使用するテクノロジです。(現時点では、データベースのような永続化データを扱う仕組みは持っていません。)
アプリケーション側 (ASP.NET MVC アプリケーションなど) からは、「分散」を意識することなく、ローカルのメモリー上のデータのように扱うことができ、データの分散・同期は、キャッシュ サービス (コードネーム Velocity) に任せることができます。(ただし、後述するように、プログラム側は、Velocity を強く意識した書き方になるので、現状は、ラッピングするなどの工夫が必要です。)
図示すると、以下のようになります。下図で、Caching Tier のサーバーを自由に増やしていくことで、スループットの向上を実現できます。
そこまでしてスケーラビリティをあげるようなケースは想像しずらいかもしれません。データベースの能力は決して低いわけではありません。一般のシステムなら、データベースだけでも充分でしょう。しかし、例えば、Amazon (コマース系) とか、Yahoo みたいな、あのような膨大なトラフィックを処理するサイトを構築・運営するようなケースを想像してみてください。こうした場合の多くは、こうした技術、もしくは、これに代わる類似の技術が必要とされます。ひとたびデータ層のアクセスで遅延が発生すると、引き続く膨大な処理によって、そのボトルネックはすぐに蓄積され、システム全体に甚大な影響を及ぼすことでしょう。
なお、どこで使っているのか私は知りませんが、米国の Tech Ed 2010 North America のセッションによると、Windows Azure の内部でも、この Velocity で採用されている分散アルゴリズムが使われているらしいです。(要は、実地検証を経た、オスミツキの技術、というわけです。)
インストール
Windows Server AppFabric のダウンロードについては、前回の ホスティングサービスの入門 を参照してください。
Velocity のインストールでは、まず、キャッシュの構成情報を保持するための専用のデータベースを準備します。(推奨されていませんが、データベースを使用せずファイルに構成情報を保持することも可能です。) ホスティングサービスの入門 のときに述べた要領で、SQL Server 上に空のデータベースを作成し、適当に権限を付与しておいてください。
【注記】 このデータベースは、上述の通り、構成情報の共有のために使用しています。Cache Tier で扱うインメモリデータがここに保持されるわけではありません。
Windows Server AppFabric のインストールをはじめると、インストールする機能を選ぶ画面が出てくるので、今回は、キャッシュサービスとキャッシュクライアントの両方を入れてしまいましょう。(すみません、下図は、もうインストール済みの環境で機能画面を出していますので、もしかしたら、実際は違う画面かもしれませんが。。。)
前述のアーキテクチャ図 (というほどちゃんとした図ではないですが。。。) の通り、Caching Tier に相当するサーバー部分と、そこに接続するクライアント部分 (Web Tier) のインストールは、通常は、別々におこなうことになるでしょう。今回は、超入門!ということで、両方を同じマシンに入れてしまいます。(なお、サーバー側は .NET 4 が必須ですが、クライアント側は、実は、.NET 3.5 も可能です。すみません、余談でした。。。)
インストール後の構成画面では、クラスタやキャッシュの構成情報を保存 (共有) するためのデータベース (またはファイル) を指定する画面が出てくるので、ここで、上記で作成しておいた SQL Server のデータベースを指定します。
注意点があるとすれば、インストール時に、Windows ファイアウォールを無効にしないことです。上記のアーキテクチャ図の通り、Web Tier と Caching Tier の間での通信や、Caching Tier の中のサーバーどうし (クラスター間) の通信など、ネットワーク接続をおこなうためにいくつかのポートが開いていなければいけません。Windows の既定の設定では、Windows ファイアウォールによって、ポートはバリバリ閉じてしまっていますが、インストール時に、これらの必要なポートを開けてくれます。(開けるかどうかチェックする画面が出てきます。) インストール時に Windows ファイアウォールを無効にすると、この「ポートを開ける」という設定をおこなえないので、あとから Windows ファイアウォールを有効にした際に、分散キャッシュが動かなくなってしまうので注意してください。
(ただし、Windows ファイアウォールを有効にした場合には、SQL Server のポートを開けるのを忘れないようにしてください。詳細は こちら に記載しています。)
Velocity で使用するポートの既定値は以下の通りです。(既定値は、インストール時や、インストール後などに変えることができます。)
キャッシュポート : 22233
クラスターポート : 22234
判別ポート : 22235
レプリケーションポート : 22236
【注記】 なお、2 台目以降のサーバーをクラスターに追加する場合は、インストール後の構成画面で、[クラスターに参加] を選択して、[AppFabric キャッシュサービス構成データベースを登録する] のみを選択し、既存の構成データベースを選択してください。([AppFabric キャッシュサービス構成データベースを作成する] は、最初の 1 台目の構成データベースの作成時のみに選択します。)
この際も、当然のことながら、忘れずに、接続先の SQL Server 側で、リモート接続の設定 (リモート接続の許可、データベースサービスの TCP/IP プロトコル設定、SQL Server Browser サービスの設定、Windows ファイアウォールの設定、など) をおこなっておいてください。
キャッシュの設定とクラスターの起動
では、実際にこのインストールしたキャッシュサービスを使って、プログラミングをしてみましょう。
と、その前に、いくつかの設定をしておかないと使えません。
サーバー上 (Windows) で、[すべてのプログラム] – [Windows Server AppFabric] – [Windows PowerShell のキャッシュ管理] を選択すると、キャッシュ管理用の PowerShell コンソールが起動してきますので、これを使って管理をおこないます。
補足 : あるいは、普通に PowerShell を立ち上げて、
import-module distributedcacheadministration
use-cachecluster
と入力しても構いません。
補足 : 使用可能なキャッシュ関連のコマンド一覧は、下記で確認できます。
get-command -module distributedcacheadministration
まず、キャッシュにアクセス権を設定します。
既定のアクセス権 (セキュリティ) では、誰もアクセスできない状態ですから、以下の通り実行して、ユーザーに権限を付与します。下記で、「domainuser」 の箇所は、実際にキャッシュにアクセスするユーザー (アプリ側からアクセスするユーザー) を指定してください。特に、IIS 上でキャッシュクライアントを使用する場合は、アプリケーションプールの ID (アカウント) にアクセス権を付与しないといけないので、要注意です。(なお、DMZ の中で構成する場合など、このセキュリティが邪魔な場合は、アクセス権自体をオフにすることもできます。う~ん、どうしても余談を書いてしまう。。。)
Grant-CacheAllowedClientAccount domainuser
そして、クラスターを起動します。以下の通り入力します。(クラスターに複数台のサーバーがある場合は、すべてのサーバー上のサービスが起動します。)
start-cachecluster
さいごに、「キャッシュ」 (入れ物) を作成しないといけません。このコンソール上で、
new-cache HogeHoge
と入力すると、「HogeHoge」という名前のキャッシュが作成されます。(作成したキャッシュを確認するには、get-cache と入力します。)
キャッシュサービスを使ったプログラミング
ということで、準備完了です。
キャッシュのクライアント側で (といっても、今回はサーバーとクライアントが同じマシンですが)、Visual Studio 2010 のプロジェクトを新規作成し、キャッシュを使用するため、以下の 2 つのアセンブリを参照追加します。(ここで、「Sysnative」と記載している点に注意してください。実際には system32 フォルダの下に入っていますが、64 bit 環境のマシンの場合、Visual Studio 自身が 32 bit ですので、リダイレクト によって syswow64 に飛ばされてしまうためです。)
%windir%\Sysnative\AppFabric
Microsoft.ApplicationServer.Caching.Core.dll
Microsoft.ApplicationServer.Caching.Client.dll
なお、今回は、ASP.NET の Web アプリケーションのプロジェクトを新規作成しますが、Client Profile では使用できないので、コンソールアプリケーションなどで試す際には注意してください。(Client Profile でないプロジェクトに変換して使用します。)
つぎに、プロジェクトの構成ファイル (web.config) を開き、下記の太字部分を追加します。
ここでは、使用するキャッシュサービスを 1 台設定 (マシン名とポート番号を設定) しています。(なお、どれか 1 台でも設定しておけば Cache Tier 全体のキャッシュ (サーバー上に分散されたすべてのキャッシュ) を使用できます。動作の詳細は、ここでは省略します。。。)
<configuration> <configSections> <section name="dataCacheClient" type="Microsoft.ApplicationServer.Caching.DataCacheClientSection, Microsoft.ApplicationServer.Caching.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </configSections> <dataCacheClient> <hosts> <!-- 使用するキャッシュサービスを列挙 (今回は1台) --> <host name="localhost" cachePort="22233"/> </hosts> </dataCacheClient> . . .
Default.aspx.cs に、以下のコードを記述します。
. . .using Microsoft.ApplicationServer.Caching;protected void Page_Load(object sender, EventArgs e){ var factory = new DataCacheFactory(); var cache = factory.GetCache("HogeHoge"); var test = cache.Get("Foo"); // cache["Foo"] でも良い if (test == null) { cache.Add("Foo", "test"); // ここも、cache["Foo"] という方法で書けます test = "test (new !)"; } Label1.Text = (string)test;}
以上、プログラムの作成完了です。上記のコードの通り、Get/Put/Add/Remove を主体とした、Key-Value 型のデータアクセスになります。
【注記】 実際の開発では、上記のように、ページがロードされるたびにファクトリー (DataCacheFactory) の作成を毎回おこなうことは避けたほうが良いでしょう。(オーバーヘッドの原因となります。static 変数などを使用して保持しておくと良いでしょう。) 上記は、サンプル コードとして記載しています。
実行すると、初回は、ラベルに「test (new !)」と表示され、2 回目からは (ページのリロードなどをおこなうと)、メモリ中にロードされたキャッシュデータが使用されるので、「test」と表示されます。
上記はサンプルとして文字列「test」を設定していますが、任意の .NET オブジェクトを入れられますので、単一の値だけでなく、付帯情報なども自由に扱うことができます。(インメモリデータですので、シリアライズ可能でないオブジェクトも扱えます。 2010/08 訂正 : すみません!ここ、誤りです。シリアライズ可能なデータを扱います。)
ちなみに、PowerShell で、以下の通り実行すると、キャッシュクラスターが再起動されるので、上記のキャッシュはすべてクリアされ、ページを表示すると、また「test (new !)」と表示されるはずです。(ただし、15 秒程度待ってから実行してください。。。)
restart-cachecluster
ところで、中でどうやって動いてるんでしょうね? 一貫性ってちゃんと保たれるんでしょうか? キャッシュデータの内容って、いつ消えるんでしょう? Azure ストレージのテーブルストレージのようにパーティションって作れないんでしょうか? 可用性って維持されるんでしょうか? セキュリティはどういう考え方なんでしょう? ASP.NET の Session も似たことができますよね? Web サーバーの出力キャッシュとの関係も気になりますね? ADO.NET Entity Framework などのセカンドレベルキャッシュとして扱えないのでしょうか? Azure 上での対応は? 並列の計算ってどうするの? . . . 知れば知るほど、いろいろ気になりますね。。。
Categories: Uncategorized
6 replies»