第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 イイネ!