.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 厳密にはもう少し複雑なシリアル化処理がなされているが、ここでは簡単のため上記のように考えて構わない(このように考えても算出されるデータサイズは大きくは変化しない)。
 
C#の場合

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;
    }
  }
}
VB.NETの場合

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以下に抑える。

 INDEX
  .NETエンタープライズWebアプリケーション 開発技術大全
  Sessionオブジェクト
    1.Sessionオブジェクトに格納可能なデータ
    2.Sessionデータの保存場所と耐障害性(ステートサービスとステートデータベース)
  3.Sessionデータのサイズ(1)
    4.Sessionデータのサイズ(2)
    5.パーソナライズ、セッション、認証済みアクセスの違いと使い分け
    6.画面遷移制御とアプリケーションコントローラ(1)
    7.画面遷移制御とアプリケーションコントローラ(2)
 
インデックス・ページヘ  「.NETエンタープライズWebアプリケーション開発技術大全」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間