[ ASP.NET ] データキャッシュでサーバの負荷軽減 ( Cache )

Pocket

アプリケーションデータキャッシュを使用して更新頻度の低いデータをメモリにキャッシュすることで、サーバ負荷(主にディスクIO)を軽減させることになりますのでパフォーマンスの向上が期待できるようになります。具体的には、Cache.InsertCache.Add メソッドでキャッシュを作成、 Cache.Get メソッドでキャッシュデータを取得します。本ページではそのサンプルコードを掲載しています。

スポンサーリンク

キャッシュ作成と取得

データキャッシュの作成と取得を行うサンプルコードになります。詳細はコメントを参照ください。

VB.NET

    Dim key As String = "key" ' キャッシュキー

    ' キャッシュからデータの読み込み
    Dim data As String = Cache.Get(key)

    'キャッシュにデータが存在しない場合はデータをファイルから読み込む
    If (data Is Nothing) Then
        'data.txt を読み込みキャッシュに入れる
        Using sr As New System.IO.StreamReader(Server.MapPath("data.txt"), _
                                               System.Text.Encoding.Default)

            data = sr.ReadToEnd()

            'ファイルの内容をすべて読み込みキャッシュに入れる
            Cache.Insert(key, data)

            sr.Close()
        End Using
    End If

    '---------------------------------------------
    ' 読み込んだキャッシュデータを使って何か処理する
    '---------------------------------------------

C#

    string key = "key"; // キャッシュキー

    // キャッシュからデータの読み込み
    string data = (string) Cache.Get(key);

    // キャッシュにデータが存在しない場合はデータをファイルから読み込む
    if (data == null) {
        // data.txt を読み込みキャッシュに入れる
        using (System.IO.StreamReader sr = new System.IO.StreamReader(Server.MapPath("data.txt"), 
                                               System.Text.Encoding.Default)) {

            data = sr.ReadToEnd();

            // ファイルの内容をすべて読み込みキャッシュに入れる
            Cache.Insert(key, data);

            sr.Close();
        }
    }

    //---------------------------------------------
    // 読み込んだキャッシュデータを使って何か処理する
    //---------------------------------------------

実データの更新によってキャッシュを自動的に破棄する

上記のサンプルコードでは、テキストファイル ( data.txt ) の内容が更新された場合、キャッシュとテキストファイルの間で差分が生じます。差分が許容できない場合は、テキストファイルの更新によってキャッシュを破棄する必要があります。

次のサンプルでは、キャッシュとテキストファイルの依存関係を設定し、テキストファイルが更新されると自動的にキャッシュの内容を破棄しています。

VB.NET

    ' data.txt が更新された場合はキャッシュを破棄する
    Cache.Insert(key, data, _
                 New System.Web.Caching.CacheDependency(Server.MapPath("data.txt")))

C#

    // data.txt が更新された場合はキャッシュを破棄する
    Cache.Insert(key, data,
                 new System.Web.Caching.CacheDependency(Server.MapPath("data.txt")));

キャッシュに有効期限を設定する

キャッシュのデータと実データとの差分を許容することが出来るのであれば、キャッシュに有効期限を設定することも1つの方法です。

有効期限には、キャッシュが有効期限切れになる正確な時間を指定する絶対有効期限設定と、キャッシュがが最後にアクセスされてから期限切れになるまでの期間を指定するスライド式有効期限があります。

VB.NET

    ' 3 分間の絶対有効期限を付けてキャッシュにアイテムを追加
    Cache.Insert(key, data, Nothing, _
                 DateTime.Now.AddMinutes(3.0), _
                 TimeSpan.Zero)

    ' 3 分間のスライド式有効期限を付けてキャッシュにアイテムを追加
    Cache.Insert(key, data, Nothing, _
                 System.Web.Caching.Cache.NoAbsoluteExpiration, _
                 New TimeSpan(0, 3, 0))

C#

    // 3 分間の絶対有効期限を付けてキャッシュにアイテムを追加
    Cache.Insert(key, data, null, 
                 DateTime.Now.AddMinutes(3d),
                 System.Web.Caching.Cache.NoSlidingExpiration);

    // 3 分間のスライド式有効期限を付けてキャッシュにアイテムを追加
    Cache.Insert(key, data, null, 
                 System.Web.Caching.Cache.NoAbsoluteExpiration, 
                 new TimeSpan(0, 3, 0));

キャッシュに優先度をつける

キャッシュの優先度は、 CacheItemPriority 列挙体で設定することができます。キャッシュは優先度の低いものから削除されることになります。

VB.NET

    ' 優先度を付けてキャッシュにアイテムを追加
    Cache.Insert(key, data, Nothing, _
                 System.Web.Caching.Cache.NoAbsoluteExpiration, _
                 System.Web.Caching.Cache.NoSlidingExpiration, _
                 System.Web.Caching.CacheItemPriority.High, Nothing)

C#

    // 優先度を付けてキャッシュにアイテムを追加
    Cache.Insert(key, data, null, 
                 System.Web.Caching.Cache.NoAbsoluteExpiration,
                 System.Web.Caching.Cache.NoSlidingExpiration,
                 System.Web.Caching.CacheItemPriority.High, null);

キャッシュが削除されたときに呼び出されるコールバックを登録する

キャッシュが削除された時に通知が必要な場合は、コールバックメソッドを登録することも出来ます。詳細はサンプル内のコメントを参照ください。

VB.NET

Imports System.Web.Caching

Partial Public Class _Default
    Inherits System.Web.UI.Page

    Private ReadOnly key As String = "key" ' キャッシュキー

    Protected Sub Page_Load(ByVal sender As Object, _
                            ByVal e As System.EventArgs) Handles Me.Load

        ' キャッシュからデータの読み込み
        Dim data As String = Cache.Get(key)

        'キャッシュにデータが存在しない場合はデータをファイルから読み込む
        If (data Is Nothing) Then
            data = CreateCache()
        End If

        '---------------------------------------------
        ' 読み込んだキャッシュデータを使って何か処理する
        '---------------------------------------------

    End Sub

    '' キャッシュを作成する
    Protected Function CreateCache()
        Dim data As String
        'data.txt を読み込みキャッシュに入れる
        Using sr As New System.IO.StreamReader(Server.MapPath("data.txt"), _
                                               System.Text.Encoding.Default)

            data = sr.ReadToEnd()
            sr.Close()

            ' ファイルの内容をすべて読み込みキャッシュに入れる
            ' ・データファイルが更新された場合はキャッシュを破棄
            ' ・1分後にキャッシュを破棄
            Cache.Insert(key, data, _
                         New System.Web.Caching.CacheDependency(Server.MapPath("data.txt")), _
                         DateTime.Now.AddMinutes(1D), _
                         System.Web.Caching.Cache.NoSlidingExpiration, _
                         CacheItemPriority.Default, _
                         New CacheItemRemovedCallback(AddressOf CacheRemovedCallback))

        End Using

        Return data

    End Function

    '' キャッシュが切れた場合のコールバックハンドラ
    Public Sub CacheRemovedCallback(ByVal key As String, _
                                     ByVal value As Object, _
                                     ByVal removedReason As CacheItemRemovedReason)
        ' キャッシュ切れの場合は再作成する
        CreateCache()

        ' キャッシュの有効期限が切れた場合
        ' removedReason == CacheItemRemovedReason.Expired;
        '
        ' データファイルが更新された場合
        ' removedReason == CacheItemRemovedReason.DependencyChanged

    End Sub
End Class

C#

using System;
using System.Web.Caching;

namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        // キャッシュのキー
        private readonly string key = "key";

        protected void Page_Load(object sender, EventArgs e)
        {
            // キャッシュからデータの読み込み
            string data = (string) Cache.Get(key);

            // キャッシュにデータが存在しない場合はデータをファイルから読み込む
            if (data == null) {
                data = CreateCache();
            }

            //---------------------------------------------
            // 読み込んだキャッシュデータを使って何か処理する
            //---------------------------------------------
        }

        /*
         * キャッシュを作成する
         */
        protected string CreateCache()
        {
            string data;
            // data.txt を読み込みキャッシュに入れる
            using (System.IO.StreamReader sr = new System.IO.StreamReader(Server.MapPath("data.txt"),
                                                   System.Text.Encoding.Default))
            {
                // データファイルを読み込む
                data = sr.ReadToEnd();
                sr.Close();

                // ファイルの内容をすべて読み込みキャッシュに入れる
                // ・データファイルが更新された場合はキャッシュを破棄
                // ・1分後にキャッシュを破棄
                Cache.Insert(key, data,
                             new System.Web.Caching.CacheDependency(Server.MapPath("data.txt")),
                             DateTime.Now.AddMinutes(1d),
                             System.Web.Caching.Cache.NoSlidingExpiration,
                             CacheItemPriority.Default,
                             new CacheItemRemovedCallback(CacheRemovedCallback));

            }
            return data;
        }

        /*
         * キャッシュが切れた場合に呼び出されるコールバックハンドラ
         */
        protected void CacheRemovedCallback(String key, object value,
                                            CacheItemRemovedReason removedReason)
        {
            // キャッシュ切れの場合は再作成する
            CreateCache();

            // キャッシュの有効期限が切れた場合
            // removedReason == CacheItemRemovedReason.Expired;
            //
            // データファイルが更新された場合
            // removedReason == CacheItemRemovedReason.DependencyChanged
        }
    }
}
参考
スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *