Azure における最新の Redis Cache サービスについては「Azure Redis Cache の使用 (.NET, PHP, Node.js)」に記載しました。(以下は、古い記事です。)
関連ナンバー
- 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 Japan ではかなりお茶を濁した表現になってしまいましたが、先日開催された PDC 10 で、Windows Azure AppFabric Caching が遂にアナウンスされました。( ゆっくりとですが、Windows Server AppFabric と Windows Azure AppFabric の垣根が低くなってきました . . .)
Windows Azure AppFabric SDK V2.0 CTP – October 2010 Update (英語) :
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=d89640fc-c552-446e-aead-b1e0d940f31b
Windows Azure AppFabric Labs (ベータ用) :
http://portal.appfabriclabs.com/
まずは、Tech Ed Japan 2010 の復習になりますが、この AppFabric の Caching (Windows Server AppFabric の Cache Services) について、どのような機能が使えるのかをザッと復習しておきましょう。
なお、基本的な AppFabric caching の使用方法 (チュートリアル) については、以前 こちら に掲載しましたので、ご参照ください。
補足 : なお、Windows Azure caching では、セキュリティも、ACS トークンを使用した方法が採用されています。また、下記の Region、Tag、Notification (通知)、HA などについても、現在の Windows Azure caching には実装されていないので注意してください。(使用できる API も、一部、制限されています。) 2012/06 削除
Region と Tag
Region と Tag を使用して、格納する Key-Value ペアのキャッシュ アイテム (データ) に対して、検索用のグループ化をおこなうことができます。
まず、Region (領域) は、「グループ化」という表現がまさにふさわしく、アイテムを排他的に分類します。一方、Tag (タグ) は、検索用のタグ付けに相当し、Region と異なり、1 つのアイテムに対して複数のタグを設定できます。
例えば、下図を参照してください。さまざまな購入品のアイテムが登録されている場合、下記の通り、PC (パソコン) というグループ化された Region を作成し、この中に、「ビジネス用」、「ノート型」などの Tag を設定できます。
Region と Tag を設定すると、下記の通り、その単位で一括検索やバルク削除などをおこなうことができます。(Tag では、GetObjectsByAllTags、GetObjectsByAnyTag などを使用した And / Or 検索も可能です。ただし、ノードをたどった取得になるため、重複検索などがおこなわれる点に注意してください。)
. . .cache.CreateRegion("PC");cache.Add("prod1", "notebook", "PC");PCItem obj = (PCItem) cache.Get("prod1", "PC");var cache = factory.GetCache("HogeHoge");cache.CreateRegion("PC");DataCacheTag tag1 = new DataCacheTag("note");DataCacheTag tag2 = new DataCacheTag("business");cache.Add("prod1",obj1,new List<DataCacheTag> {tag1},"PC");cache.Add("prod2",obj2,new List<DataCacheTag> {tag2}, "PC");cache.Add("prod3",obj3,new List<DataCacheTag>{tag1,tag2}, "PC");IEnumerable<KeyValuePair<string, object>> result = cache.GetObjectsByTag(tag1, "PC"); // prod1, prod3. . .
なお、Region は パーティション化の対象となり、同じ Region のアイテムは同じホストに配置されます。このため、異なる Region に対して同じ Tag を付けても、結局、Region ごとにしか検索できないので注意してください。
キャッシュ アイテムのバージョン
アイテムには「バージョン」が付与されます。ただし、このバージョンの概念は、「世代すべての管理」とはやや異なる概念ですので注意してください。
通常、「バージョン管理」というと、過去のすべてのバージョンのアイテムが管理され、過去のアイテムへのロールバックなども可能な場合が多いでしょう。しかし、Velocity における「バージョン」は、こうしたバージョン管理ではなく、単に、アイテムに対してバージョン キーを付与するというものです。このため、例えば、いつの世代のアイテムであるかアプリケーションから検証する場合などに使用できます。
以下に、サンプルを掲載します。
. . .DataCacheItemVersion ver1 = cache.Add("Foo", obj1);DataCacheItemVersion ver2 = cache.Put("Foo", obj2);DataCacheItemVersion ver = default(DataCacheItemVersion);MyObj res = (MyObj) cache.Get("Foo", out ver);if (ver.CompareTo(ver1) == 0) Console.WriteLine("res is Version1"); // not hitelse if(ver.CompareTo(ver2) == 0) Console.WriteLine("res is Version2"); // hit !. . .
キャッシュ アイテムのセキュリティ
Velocity で管理されるアイテムは、セキュリティ モード (Security Mode) と保護レベル (Protection Level) という 2 つの概念で保護できます。
None | いかなるクライアントもアクセス可能です |
Transport (既定) | 許可された Windows アカウント(ユーザー、グループ、マシン) のみが接続可能です |
None | 保護しないモード |
Sign | データの整合性チェックをおこない、データの不正操作や改ざんを防止します (Security Mode が Transport の場合のみ有効です) |
EncryptAndSign (既定) | 上記の改ざん防止に加え、データを暗号化することで外部からの読み取りも防止します (Security Mode が Transport の場合のみ有効です) |
このセキュリティの設定は、サーバー側とクライアント側の双方でおこないます。(クライアント側は、.config に記載する方法と、プログラムを使用して securityProperties に設定する方法があります。)
このセキュリティ設定ですが、既定では、上記の通り EncryptAndSign になっていますが、無論、セキュリティ設定によるオーバーヘッドも無視できない場合があるので、注意してください。下記は、PowerShell を使って、サーバー側のセキュリティ設定を無効にする場合の例です。
Set-CacheClusterSecurity -SecurityMode None -ProtectionLevel None
キャッシュ アイテムのライフサイクル
アイテムは、既定では揮発的なものです。
そして、以下の Expiration と Eviction の概念の組み合わせで、この生存方針を設定できます。
Expirable | False にすると下記の Eviction のみが評価され、True にすると有効期限 (時間) が評価されます (既定は True です) |
default TTL | Time To Live (生存時間) を設定します (既定は 10 分です) |
EvictionType | ここは、現在、None (Eviction なし) か LRU (least recently used, 使用頻度が高いアイテムを優先するアルゴリズム) しか指定できません (既定は LRU です) |
このライフサイクルは、PowerShell やサーバー上の構成を使ってキャッシュごとに設定しますが、キャッシュ アイテムごとに生存時間 (TTL) を上書きできます。
なお、Expiration と Eviction を無効にすると、生存状態をすべてアプリケーションで管理できます。(下記は、PowerShell での設定例です。) しかし、それでも、ホストが停止した場合 (かつ、HA オプションが有効でない場合) など、アイテムが消滅する可能性は常にあるので、基本的に、揮発的なデータを管理するものとして使用してください。
New-Cache HogeHoge -Expirable false -Evication None
ローカル キャッシュ
キャッシュ アイテム (の Primary) は、分散された (サーバーの) ホスト上のどこか 1 箇所に必ず存在し、クライアント (Web アプリケーションなど) からアイテムを取得する場合、この問い合わせはルーティングされ、該当のホストからアイテムが取得されます。(この既定の状態を Partitioned Cache と呼びます。)
ここで紹介するローカル キャッシュでは、参照系データなどの場合に、このアイテムをクライアント側にキャッシュすることで、さらに効率化 (呼び出しのオーバーヘッドの低減) をおこなうことができます。また、アイテムは、シリアライズされず、参照が使用されるため、大きなデータなどではスループットはさらに向上します。(なお、ローカルにアイテムがない場合は、サーバーからアイテムが取得され、逆シリアライズされます。)
このローカル キャッシュには、時限方式の TimeoutBased と、ポーリングベースの NotificationsBased が使用できます。下記の構成 (クライアント側の .config) は、NotificationBased を使用している設定例です。
. . .<dataCacheClient> <localCache isEnabled="true" sync="NotificationBased" objectCount="100000" ttlValue="300" /> <!--(optional) キャッシュ更新通知のポーリング間隔 --> <clientNotification pollInterval="300" /> . . .
localCache (上記) には、以下の属性を設定できます。
isEnabled | True に設定することで、ローカル キャッシュを有効化します |
sync | 上述した TimeoutBased (時限方式によるキャッシュ無効化) と NotificationsBased (時限方式に加え、通知方式によるキャッシュ無効化) の設定です (既定では、300 秒ごとにポーリングをおこないます) |
objectCount | クライアント側にキャッシュできるデータの個数を指定します (既定値は 100000 です) |
ttlValue | 無効化の時間設定 (単位は秒) です (既定値は 300 です) |
ローカル キャッシュでは、そのメカニズムから、データ一貫性が犠牲になるという点に注意してください。
また、Tech Ed Japan 2010 でも説明したように、このローカル キャッシュは、キャッシュ ファクトリー単位で設定されます。(プログラム コードを使って、ファクトリーごとに設定することも可能です。詳細は、「Velocity における Partitioned キャッシュとローカルキャッシュの併用」 を参照してください。) このため、例えば、ASP.NET の Web アプリケーションなどで、毎回ファクトリーを作成しなおすようにプログラミングしている場合は、ローカル キャッシュが効かなくなってしまいますので注意してください。(ASP.NET の場合、キャッシュ ファクトリーを、Application、Session、static 変数などに保持します。)
悲観ロック (Pessimistic locking)
上述の通り、Partitioned Cache では、単一のホスト上のアイテムが使用されるため、アイテムの書き込み / 読み取りの一貫性が保証されます。しかし、例えば、データを読み込んでカウント アップするようなケースなど、一連の時間を伴う処理での一貫性は保証されません。
こうした場合には、下記の通り、悲観的ロックのための API (GetAndLock / PutAndUnlock / Unlock) が使用できます。
. . .obj1 = cache.GetAndLock("Foo", TimeSpan.FromSeconds(10), out handle, true);任意の処理の実行 ...cache.PutAndUnlock("Foo", obj2, handle);. . .
この API ですが、現状は、「待機」の仕組みを持っていません。(このため、待機をおこなうには、例外を処理する必要があります。) また、ロック時には、他からの Put 処理なども保護されません。(あくまでも、アプリケーション側で、統一的に PutAndLock をおこなった場合に、ロックが有効になります。)
このため、悲観的ロックを使用する場合は、アプリケーション側でも、このロック メカニズムを意識した実装をおこなう必要があります。
通知 (Notification)
Velocity では、キャッシュ / Region / アイテムの各レベルの更新を通知できます。
例えば、以下は、キャッシュ全体で、アイテムと Region に発生した更新処理を通知するサンプルです。
. . .using Microsoft.ApplicationServer.Caching;static void Main(string[] args){ DataCacheOperations allCacheOperations = DataCacheOperations.AddItem | DataCacheOperations.ReplaceItem | DataCacheOperations.RemoveItem | DataCacheOperations.CreateRegion | DataCacheOperations.ClearRegion | DataCacheOperations.RemoveRegion; var factory = new DataCacheFactory(); var cache = factory.GetCache("HogeHoge"); cache.AddCacheLevelCallback(allCacheOperations, delegate( string myCacheName, string myRegion, string myKey, DataCacheItemVersion itemVersion, DataCacheOperations OperationId, DataCacheNotificationDescriptor nd) { Console.WriteLine("Cache-Level Notification"); Console.WriteLine("tCache:{0}", myCacheName); Console.WriteLine("tRegion:{0}", myRegion); Console.WriteLine("tKey:{0}", myKey); Console.WriteLine("tOperationId:{0}", OperationId.ToString()); Console.WriteLine("tDescriptor:{0}", nd.ToString()); }); Console.WriteLine("終了するには Enter"); Console.ReadLine();}
<configuration> <configSections> . . . </configSections> <dataCacheClient> <hosts> <host name="kkdeveva01" cachePort="22233"/> </hosts> <clientNotification pollInterval="10" /> </dataCacheClient> . . .
この通知ですが、上記の構成 (.config) を見ていただくとわかるように、ポーリングによる通知メカニズムであるという点に注意してください。このため、現状は、キャッシュの更新処理をトリガするような Cache through feature のような目的で使用することはできません。
また Remove も通知されますが、expiration / eviction による通知は、非常に遅いタイミングで返ってきますので注意してください。
高可用性オプション (High Availability, HA)
AppFabric cache では、障害発生によるノード (マシン) の突然の停止の際に、キャッシュ内のデータをロストしないための設定が可能です。Windows PowerShell で、下記の通り設定します。
New-Cache HogeHoge -Secondaries 1
上記の設定をおこなうことで、Key-Value のアイテムは、常に、Primary と Secondary の双方が異なるノード上に配置されるようになります。(書き込みをおこなうと、Primary、Secondary の双方に、同期的に書き込みをおこないます。) そして、ノードがトラブルなどで停止した場合も、Primary、Secondary の再配置をして、引き続き、高可用性を保障します。
この動きのイメージを、下記のスライド ショーで示します。(下図を Click してください)
なお、Windows Server 2008 以降の Enterprise Edition / Datacenter Edition 以上のエディションが必要となるので、注意してください。
管理 / 監視
以前、「Windows Server AppFabric caching 入門」で解説したように、Windows PowerShell を使って、クラスター、キャッシュの操作 (開始/停止、キャッシュ作成、など) がおこなえますが、こうした「操作」以外の管理用途でも Windows PowerShell を活用することができます。
例えば、以下のコマンドでは、そのノードに配置されているアイテムの状況 (個数など) を確認できます。
Get-CacheStatistics -HostName machine1 -CachePort 22233
また、プログラミングを使って、構成 (config) の設定、オブジェクトの取得など、管理的な記述もおこなえます。例えば、下記では、すべての Region のすべてのアイテム (Key-Value) の内容を確認しています。(C# の例です。)
string cachename = Console.ReadLine();var factory = new DataCacheFactory();var cache = factory.GetCache(cachename);List<string> regions = (List<string>) cache.GetSystemRegions();foreach (string region in regions){ IEnumerable<KeyValuePair<string, object>> items = cache.GetObjectsInRegion(region); if (items.Count<KeyValuePair<string, object>>() > 0) Console.WriteLine("Region:{0}", region); foreach (KeyValuePair<string, object> item in items) { Console.WriteLine("Key:{0} Value:{1}", item.Key, item.Value.ToString()); }}
Windows PowerShell の Get-CacheRegion (Region の一覧と、ホスト名が返ってきます) と上記を組み合わせれば、どのアイテムが、どのホストにあるか、一覧を取得することもできます。チューニングや状態確認などをおこなう上で、Windows PowerShell やプログラム コードが非常に役に立つことがおわかり頂けるでしょう。
また、サービス起動時のエラーなど基本的なものはイベント ビューアー (eventvwr) で確認できますが、キャッシュへの操作内容 (Get など) の監視など、細かな操作の監視をおこなう場合は、Windows SDK の tracelog.exe を使用して、以下の通り、ETW トレースをおこないます。
rem -- ETW トレースを開始して test.etl に出力tracelog -start debugtrace -f test.etl -guid "C:\Windows\System32\AppFabric\Manifests\Provider\GUID.txt" -level 5 -cir 512rem -- ETW トレースを終了tracelog -stop debugtracerem -- トレースの内容を CSV として出力tracerpt .test.etl -o test.csv -of CSV
アプリケーションへの応用
Velocity では、基本的には、Get/Put/Add/Remove などのプリミティブ (Primitive) な操作を提供するのみで、アプリケーション レベルの Abstraction は、開発者みずからが構築します。
しかし、いくつかの基本的な Abstration (アプリケーション) については、下記の通り、既にさまざまな形で提供されていますので、いくつかを紹介します。
- ASP.NET Session での使用 :
ASP.NET の Session データの格納先としてこのインメモリ キャッシュ (AppFabric Cache) を使いたい場合、実は、Velocity が提供しているアセンブリの中に、既にこのためのプロバイダー クラスが提供されています。以下は、このクラス (DataCacheSessionStoreProvider) を使って sessionState を構成したサンプルです。(Tech Ed Japan で説明したいくつかの注意点がありますが、ここでは、これらの説明は省略します。。。)
<sessionState mode="Custom" customProvider="MyVelocity"> <providers><add name="MyVelocity" type="Microsoft.ApplicationServer.Caching.DataCacheSessionStoreProvider, Microsoft.ApplicationServer.Caching.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3,856ad364e35" cacheName="SessionTest"/> </providers></sessionState>
- OR マッパーの second level cache としての使用 :
ADO.NET Entity Framework や NHibernate などの second level cache として使用する場合、CodePlex や SourceForge に Velocity 用のライブラリが提供されています。 - ASP.NET のキャッシュ プロバイダー :
ASP.NET 4 では、System.Web.Caching.OutputCacheProvider クラスから派生して独自のキャッシュ プロバイダーを作成できます。
この手法を使用して、Velocity を使用した出力キャッシュのプロバイダーを構築することも可能です。(なお、Windows Azure caching では、このプロバイダー クラスが既定で提供されています。)
補足 : ASP.NET Session で使用する際には、下記の通り、アプリケーション プールの Virtual Account にもキャッシュの利用権限を付与しておきましょう。
Grant-CacheAllowedClientAccount “IIS APPPOOLASP.NET v4.0”
以上、スタートされる方のために、まず、どのようなことが可能か大まかに解説しました。以降の詳細 (疑問等) は、是非 MSDN をご活用ください。
Categories: Uncategorized
5 replies»