Windows Azure AppFabric Caching を使ってみる

ASP.NET Universal ProvidersおよびカスタムのHighPerformanceSessionStateProviderを見てきたわけですが、本命(?)のWindows Azure AppFabric Cachingだと、どんなもんなんでしょうか。

構成等は今までと同じで、Windows Azure AppFabric Cachingも同じエリア(東アジア)に作って試してみました。

※Azure AppFabric Cachingの使い方等は適当に検索で(
※アセンブリ追加してWeb.configにもろもろ追加+セッションプロバイダの変更をしただけです。(ちなみに今回はSSLなエンドポイントを使用)

↓結果

えらい早い ( ゚д゚) 12万セッションだだだっと作るのに3分ぐらい。

作りながら同じセッションで継続アクセスした場合はこんな感じ

削除処理とかはAzure AppFabric Caching側が面倒みるのでいつかわかりませんが、きちんと破棄されたりしているようです。

とまぁこんな感じでした。

ASP.NET Univarsal Providers のセッションプロバイダを使ってみる (3)

第1回第2回に続いて第3回です。

前回はそのまんまASP.NET MVC3ロールに含まれてるASP.NET Univarsal Providersを使って軽く負荷テストしたりしてみました。
結果は想定通りだったわけですが、なんと、たけぱらさんにこんなコメントをつけて頂き、しかもHighPerformanceSessionStateProvider という実装までしてくださいました。

こりゃー再度テストしてみないといけないな!ということで。

条件は前回と同じくAzure上にSサイズで5インスタンスほど、たけぱらさん作HighPerformanceSessionStateProviderを使ったMVC3ロールを展開。クライアントも同様にSサイズなWorkerロールを20インスタンスほど作って並行で6000セッションづつ作りまくる感じにしました。

HighPerformanceSessionStateProvider はたけぱらさんのBlogからコピペ。ただSQL Azureで利用する際に1点だけ修正が必要なので注意です。

CreateSessionIndex メソッド内

		private void CreateSessionIndex(ConnectionStringSettings connectionStringSettings)
		{
			ExecuteSql(connectionStringSettings, (factory, command) =>
			{
				command.CommandText = @"IF not EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[Sessions]') AND name = N'IX_Sessions')
begin
CREATE NONCLUSTERED INDEX [IX_Sessions] ON [dbo].[Sessions] 
(
	[Expires] ASC
)
end
";
			});
		}

SQL Azure上で利用できないT-SQLの構文があるので、上記10行目に書かれてた「ON [PRIMARY]」を削除します。

Web.configも書き換えたら準備完了です。

で、実際に見てみると…だいぶ早い感じ。セッションタイムアウトは10分にしてたのですが、6000セッションx20作成中に生存してるセッションが2万弱とかだったのに対し4万弱ほど作れてたりします。

ログみると

タイムアウトになったりなNGが5000ちょいほどありますが…概ね良好な感じですね。
※タイムアウトなるのはコードの問題な気がしないでもない…例外まで補足してなかったので詳細不明(ひょっとしたらSQL Azure側?うーん)

で、前回まともに動作しなかった同じセッションIDで更新したり、ごみセッションを削除する処理ですが

こんな感じでゴリゴリセッション作成してる間でも500msとかでアクセスできてますね。(=セッションテーブルの更新もOK)

また最後の15分経過後のアクセスも5秒かかっていますが問題なくできてます。
ちなみにこの時のごみセッション数は32000弱。

ちょっとしたひと手間でまともに使える感じがします!

HighPerformanceSessionStateProvider イイネ!

ASP.NET Univarsal Providers のセッションプロバイダを使ってみる (2)

全開前回の続きです。

前回、セッションIDにAppDomainAppIdの値が付与されるから複数台な環境だとAppDomainAppIdを合わせておかないとセッション共有ができないんじゃね?という話をしました。

理屈上はそうなので、どうしようかと思って実際にWindows Azure上で見てみると…

おや。複数インスタンスでもAppDomainAppId同じですね。Full IISでマルチサイトしてみましたけど、(法則性はよくわかりませんが)全部同じようです。
想像するにWeb Roleを初期化する際、サービス定義ファイル等に基づいてサイトを作成しますがAppDomainAppIdも指定して作成している感じですか。

というわけでセッションIDに関する懸念はWindows Azure上で使う分には気にしなくて良さそうですね。

さて次はパフォーマンスの話。

前回見てみた限りだと明らかにパフォーマンスに問題がありそうな仕組みでした。
ということで実際どれぐらいなんだろう、というのをぱふぉちゅー素人であるおいらが見てみようと思います。
※言うまでもなく実際にASP.NET Univarsal Providersを採用する際はご自身で確認してください。あくまで参考程度に。

さてテストするにあたってASP.NET Univarsal Providers+SQL Azureを使用してセッション共有するようにしたWebアプリを5インスタンスで動かします。それからWebアプリにアクセスしてセッションを作成したりするWorker Roleを20インスタンスほど。

台数にあまり深い理由はないんですがセッションの応答速度みるのにサーバー自体がネックになってもなぁと思いつつ5インスタンスに。クライアント側は多めにということで20インスタンスにしました。

クライアント側は単純にWebClient使ってページを読み込むだけです。で、前後で時間を計測する感じに。

class Program
{
	static void Main(string[] args)
	{
		System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

		GetPage();

		int count = int.Parse(args[0]);

		for (int i = 0; i < count; i++)
		{
			sw.Reset();
			sw.Start();
			GetPage();
			sw.Stop();
			Console.WriteLine("{0}\t{1}",DateTime.UtcNow.ToString("yyyy/MM/dd hh:mm:ss.fff"),sw.Elapsed);
		}
	}

	static private void GetPage()
	{
		WebClient wc = new WebClient();
		using (Stream st = wc.OpenRead("http://penguindrum.cloudapp.net/"))
		{
			Encoding enc = Encoding.GetEncoding("UTF-8");
			using (StreamReader sr = new StreamReader(st, enc))
			{
				string html = sr.ReadToEnd();
				sr.Close();
				st.Close();
			}
		}

	}
}

Webアプリ側は前回と同じやつでセッションオブジェクトが無ければ現在時刻を放り込むだけの簡単仕様

とりあえずひたすらセッションを作っていくわけですが、Insert処理だとそんなに(?)重くない感じですね。
2万セッションぐらい作って(ページ取得の)平均応答時間が0.5秒ぐらい、長くて2秒。

さてセッションを作りまくるワーカー走らせてる横で、同じようにセッション作って、再度そのセッションを使って1分おきにアクセスするような(=DBを更新するような)クライアントで処理時間見てみようと思います。(※WebClientだとCookieセットできなかったのでHttpWebRequestを使用)

適当にクライアントアプリ作った所為で落ちてますが、うまく更新できるケースもあればタイムアウトでちゃんと応答が返ってこないとか、返ってきても6秒かかってるとか。ちょっと不安定。

一番最後の実行結果は、作ったタイムアウトになった2万セッションがDBに残ってる状態で新規アクセスしたときのですが、期限切れセッションを取得して削除処理が入ってるので52秒かかってます。これ他にアクセスが無い状態での結果なので…

同時アクセスがそんなになく、ユーザー数も少ないようなケース、もしくは多少応答が遅くなってもいいケースでは簡単に使えるので便利ですね。
DB側のチューニングでもう少し改善しそうですけど、あまり詳しくないので触れないでおきます。

まぁなんというか、このエントリそのものはあまり役に立たない内容でしたが、捨てるのもあれなので晒してみました。恥じらいとたくし上げ。

ASP.NET Univarsal Providers のセッションプロバイダを使ってみる

ASP.NET Univarsal Providersのセッションプロバイダって、セッションの破棄もしてくれるの?という話題から。

結論から言うと、「期限切れのセッションは削除してくれます。但しパフォーマンスに問題がありそうなやり方で。」となります。

@kazuk さんにさらっと見てもらえたので先に結論がわかりました。ありがとうございます。

さて実際にその様を見てみましょうか。

続きを読む

ASP.NET Universal Providers

さっきの投稿でも書いた System.Web.Providers ですが、名称としては ASP.NET Universal Providers というそうです。

簡単に何をするものか説明すると、「ASP.NET におけるセッションステート、メンバシップ、ロール、プロファイル機能を、SQL Compact と SQL Azure にも対応させるツール」 という感じでしょうか。パクリですけど。

Node.js、Ruby、Python を Windows Azure で利用する Smarx Role ~ クラウドカバー Episode 48 より引用

ASP.NET におけるセッションステート、メンバシップ、ロール、プロファイル機能を、SQL Compact と SQL Azure にも対応させるツール “ASP.NET Universal Provider” がアルファ版としてリリースされました。

これにより、これまでのオンプレミスな Windows & SQL Server という組み合わせに加え、低トラフィックな Web サイトでは共有ホスティング & SQL Compact を利用、トラフィックが多い Web サイトでは Windows Azure & SQL Azure を利用する、といったことが可能になります。

ということで便利でナイスなプロバイダなわけですが、現時点でnugetから入手できるASP.NET Universal Providerは 0.1です。

でも、ASP.NET MVC 3 Webロールテンプレートに含まれる System.Web.Providers は1.0扱い?なんですよね。アセンブリも違うもののようです。(中身まで見たわけじゃないですがバイナリは異なる)

そのうちNugetにもあがる気はしますが、とりあえず正式版?がASP.NET MVC 3 Webロールテンプレートには含まれてるようです。

ちなみにアセンブリは<プロジェクトフォルダ>\packages\System.Web.Providers.1.0 のLibにあります。EULAやReadme.htmlもあるので使い方とか参考にどうぞ。

image

これはちゃんと使いこなしたいですね!

※EULAのどこどう見たらGoLiveなのか詳しい人に教えてもらいたいところ…ちゃんと読めという話ですが。

※EULAの補足。nugetで入手できる0.1はALPHA版ということで、商用利用が制限されています。ただ、ASP.NET MVC 3 Webロールに含まれてる1.0のほうはこの制限がないので、商用利用OK、Go-liveとみていいと思います。

image

 

いろいろ盛り込んでくれますね!Azure Team!

Windows Azure ASP.NET MVC 3 Web Role で使っているプロバイダ

先日の投稿でも書きましたが、Windows Azure Tools for Visual studio v1.4 (August 2011 Update)でASP.NET MVC 3のWebロールテンプレートが追加されました。

で、このASP.NET MVC 3なWebロールを使うと今まで面倒だったアセンブリの追加とかが不要なわけですが、そのまま何も気にせずデプロイするとエラーになります。

image

よくみる(?)画面ですね。

さて、この原因ですが Deploying the Windows Azure ASP.NET MVC 3 Web Role にもある通り、ASP.NET MVC 3 Webロールプロジェクトテンプレートに含まれてるWeb.configにて、SQL Expressなカスタムセッションを利用するようになっているのが原因です。

解決方法はWade Wegner氏が書いてるとおりSQL Azure使うように正しく接続文字列変えてあげると良いのですが、面倒な場合はsessionState属性のmodeをOffとかInProcにすればいいんじゃないでしょうか。(投げやり)

※というのもちゃんとアプリケーション作るときはこの辺きちんと考慮するだろうし、デフォルトのままデプロイしたりするのは訓練されたあじゅらーぐらいな気もするので…

まぁ、そのうち修正されるかもしれませんがちょっとしたbad know-howということで…

– 重要な補足 –

たけはらさんにTumblrで教えていただきました。

どうもこのASP.NET MVC 3 Webロールテンプレートで使っているセッションやメンバシッププロバイダ等各種プロバイダはEntityFrameworkベースのSystem.Web.Providersだそうです。

Introducing System.Web.Providers – ASP.NET Universal Providers for Session, Membership, Roles and User Profile on SQL Compact and SQL Azure – Scott Hanselman

未来を先取りテンプレート!!

ということは、Bad know-howで問題点として片付けるんじゃなくて、新しいテクノロジを活用しよう!っていう方向に持っていくべきですかね。

たけはらさんありがとうございます。

mvcConf @:Japan のセッションビデオが公開されました

mvcConf @:Japan ~ ASP.NET MVC ブートキャンプ ~ のセッションビデオが公開されたようです。

公開場所はCh.9ですよ!当日は流れなかったビデオメッセージも多数公開されていてうれしい限り。
もちろんScott Guthrie氏やScott Hanselman氏のメッセージも公開されています。

Channel 9ということもあり動画は複数エンコードから選んでダウンロードもできるしセッションスライドもダウンロードできます。

もちろん…あれ(?)もw

さてスピーカーの皆様がフォローアップ記事を書かれてるのでいくつか追加しておきます。

mvcConf @:Japan に参加してきました

6月11日に品川でmvcConf @:Japan ~ ASP.NET MVC ブートキャンプ ~が開催されました。楽しそうだったのでいろいろ無理をいって参加してきましたので軽くまとめ。(技術面はほとんど書いてないのであしからず)

ちなみにMVPなBlogに取り上げられるくらい注目度は高かったようです。

Twitterのハッシュタグは #mvcjpn だったようなので、追うことができると思います。

セッション中のつぶやきはTogetterにまとまっていました。

なお、後日Ch.9での動画公開や@ITへレポート記事が載るようです。

続きを読む

Add Deployable Assemblies を Windows Azure プロジェクトで使ってみる

※しばやん氏にASP.NET MVCだけでいいよと指摘頂いたので修正 (2011/05/29) 指摘ありがとうございます。

チャック全開兄者からパスが来たので、試してみます。

Visual Studio 2010でASP.NET MVC3 プロジェクトで開発する場合、本番環境に配置する為のアセンブリを追加したり、Binフォルダに一緒にコピーするように設定したりすごく面倒です。

特にWindows Azure上でASP.NET MVC3なWebアプリを展開する場合、気を付けないとアセンブリ不足で動作しないで凹むとかしょっちゅうです。中にはVisual Studio向けAzureプロジェクトテンプレートにMVC3を追加したり、いろいろされてる方もいらっしゃるようです。

でも面倒くさいですね(

NuGetで入るならまだしも。。

ということで、そのうち正式にWindows Azure SDKがASP.NET MVC3に対応すると思いますが、それまでのつなぎな手法を今日は紹介しておきます。

続きを読む

無聊を託つさんへ

お手紙ありがとうございます。

すっかり春の陽気で過ごしやすくなりましたね。まだまだ朝晩は冷え込みますのでお体にはお気を付けください。あ、MVPおめでとうございます。
おいらといいますと、おかげさまで元気に忙しく過ごさせて頂いています。

さて例のWCF Data ServicesをFormsAuthenticationでアレコレしてゴニョゴニョする件ですが、ASP.NET MVCのアクションメソッドでこうするとできるんだ~!という新しい知見が開けて大変興味深かったです。

ASP.NET MVCのアクションでやる場合、楽ちん・便利という視点ではなく、アプリケーション全体として見てどうなのかな?と単純に思いました。

WCF Data Servicesのみで完結させた場合は以下のような特徴が考えられます。

  • サーバーサイド(WCF Data Services側)でログオン処理を記述する必要が無い(Web.configに追記でOK)
  • ASP.NETなWebアプリケーションと分けることが出来る(代わりに仮想アプリや仮想サイトが分かれたりしますが)
    つまりMembershipプロバイダを分けることも同じものを使うこともできる

ではASP.NET MVCのアクションの場合はというと。

  • アクションを実装する必要があるが認証の方式を変えたり、ID/Password以外の要素でも評価できる(Authentication_JSON_AppService.axdの仕様に左右されない)
  • 仮想サイト(仮想アプリケーション)が1つで済む
  • Membershipプロバイダを使う必要が無い(もちろん使ってもよい)
  • きめ細かく動作を制御できる

などがありそうです。まぁどちらもにわかな人が考えた内容なので間違ってるかもしれませんが。。

個人的に思うのはやっぱりアプリケーションの構成をどうするか、認証方式をどうするか/したいか、が一番大きなポイントでしょうか。

もともとはおいらが求めた要件にマッチするのがWCF Data Servicesで完結させる方法だった、というのとWebアプリ/データアクセス/認証をできるだけ分離しておきたかったというのが大きなポイントで以前の投稿のような形式になった背景がありますので、単純な比較は難しいですね。(Federation認証等ともからんじゃったり色々…)

ということでケースバイケースという魔法のことばでぽぽぽーん集約してしまいますが、ボツネタにならず公開して頂いてよかった!と思いますです。

あぁ、この内容こそ没ネタにすべきだったかなw

あと関係ないですがTHE CODE PROJECTはいろいろ勉強になりますね。

ではでは。