|
.NETエンタープライズ
Webアプリケーション開発技術大全
Sessionオブジェクト
マイクロソフト コンサルティング本部 赤間 信幸
2004/07/15 |
|
3 Sessionデータのサイズ
Sessionオブジェクトへ巨大なデータを格納してはならない。巨大なデータを格納すると、以下の2つの弊害を引き起こすことになる。
・ スケーラビリティ(拡張性) |
|
・ Sessionデータが増えればサーバメモリの消費量が増えるので、1台のサーバで同時にサポートできるセッション数が少なくなる。 |
|
・ パフォーマンス(単体性能) |
|
・ ステートサービスやステートデータベースを利用する場合には、Sessionデータのシリアル化とデータ転送が発生する。 |
|
・ データサイズが大きくなると、これに要する時間が無視できないほど大きくなってしまう。 |
格納するデータサイズの上限を一概に設定することはできないが、1ユーザ(1セッション)あたり50KB 〜 100KB程度で済むようにアプリケーションを設計することが望ましい。以下に、Sessionデータのサイズに関する設計・実装上の注意点を整理する。
-
Sessionデータサイズの算出方法
-
サイズ肥大化に対する事前予防策
-
巨大なページング制御
-
Sessionデータの有効時間と削除処理
A. Sessionデータサイズの算出方法
Sessionデータは、BinaryFormatterクラスによりシリアル化され、ステートサービスやステートデータベースに格納される※9。このため、Sessionオブジェクトのデータサイズは、リスト2のようなプログラムにより概算することができる。
※9 厳密にはもう少し複雑なシリアル化処理がなされているが、ここでは簡単のため上記のように考えて構わない(このように考えても算出されるデータサイズは大きくは変化しない)。 |
using System;
using System.IO;
using System.Web;
using System.Runtime.Serialization.Formatters.Binary;
namespace Microsoft.Japan.Mcs.Utilities.Web
{
public class WebUtil
{
public static long CalculateSessionSize()
{
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
HttpContext hc = HttpContext.Current;
foreach (string key in hc.Session.Keys)
{
writer.Write(key);
(new BinaryFormatter()).Serialize(writer.BaseStream, hc.Session[key]);
}
writer.Flush();
long size = stream.Length;
stream.Close();
return size;
}
}
}
|
Imports System.IO
Imports System.Web
Imports System.Runtime.Serialization.Formatters.Binary
Public Class WebUtil
Public Shared Function CalculateSessionSize() As Long
Dim stream As MemoryStream = New MemoryStream()
Dim writer As BinaryWriter = New BinaryWriter(stream)
Dim hc As HttpContext = HttpContext.Current
Dim key As String
For Each key In hc.Session.Keys
writer.Write(key)
Dim bf As New BinaryFormatter()
bf.Serialize(writer.BaseStream, hc.Session(key))
Next
writer.Flush()
Dim size As Long = stream.Length
stream.Close()
Return size
End Function
End Class
|
|
リスト2 Sessionオブジェクトのデータサイズを算出するコード例 |
実際に上記のプログラムを利用して算出したデータのサイズを表2に示す。なお、DataSetのデータサイズ算出にあたっては、SQL Server 2000のNorthwindサンプルデータベース内のデータを利用した。
格納するデータ |
内容 |
概算されたサイズ |
int 型のデータ |
int a = 30; |
約60 バイト |
String 型のデータ |
string b = "akama"; |
約40 バイト |
String 型の静的配列(要素数2) |
string[] c = new string[]{"akama", "shibuya"}; |
約60 バイト |
DataSet  |
空のデータセット |
約700 バイト |
DataSet  |
Customers テーブル/ 91行 |
約36k バイト |
DataSet  |
Orders テーブル/ 830行 |
約460k バイト |
DataSet  |
Order Details テーブルとOrders テーブルを結合/ 2,155行 |
約1.5M バイト |
 |
表2 リスト2を使って算出したデータサイズ |
この表から、以下のことが言える。
- 基本データ型や、サイズの小さい静的配列のデータサイズは、ほとんど無視できるほど小さい。
- DataSetのデータサイズは、含まれるデータ量によって大幅に変化する。
環境や非機能要件にもよるが、現在のコンピュータの性能を前提にすると、数100KBを超えるDataSetをSessionオブジェクトに格納するのは避けた方がよい。データサイズがこの付近を超えると、シリアル化処理とステートサービス(またはステートデータベース)への転送処理にかなりの時間(数秒以上)を要するようになり、Webアプリケーションとして使い物にならなくなる。
このため、設計上の1つの目安として、以下のような指標が立てられることになる※10。
※10 この数値指標は1つの目安である。実際の上限値はシステム構成(ハードウェア性能など)によって変わるため、最終的にはパフォーマンステストを実施して決定することを推奨する。 |
- SessionオブジェクトにDataSetを格納する場合には、データ行数は数百行以内に抑える。
- データサイズは、100KB以下に抑える。
Insider.NET 記事ランキング
本日
月間