Windows Server AppFabric Caching

July 4, 2010

Introduction

For those of you who haven’t heard about AppFabric yet, check out the Windows Server AppFabric Learning Center on MSDN. The first version is out now and can be downloaded here.

One key functionality of AppFabric that caught my attention was its caching feature also known as Velocity (Project Code Name). To quote MSDN:

For Web applications, AppFabric provides caching capabilities to provide high-speed access, scale, and high availability to application data.

Sounds interesting, especially as I am building a web application which is going to be hosted in a web farm. Instead of using ASP.NET’s built-in caching option, which is tied to a single AppDomain and thus one web server, I can opt to use a cache powered by AppFabric which is shared across web servers.

Let’s see it in action…

Table Of Contents

Installation

Lets first install AppFabric. Download the most appropriate Windows Server AppFabric version for you on the following page:

http://www.microsoft.com/downloads/details.aspx?FamilyID=467E5AA5-C25B-4C80-A6D2-9F8FB0F337D2&displaylang=en

Start and follow the wizard. First it will ask which features you want to install. I’m only interested in the caching features so I unchecked all the rest.

Figure 1 – Feature Selection

Next you need to configure the Caching Service.

Figure 2 – Configure Caching Service

I created a new local user account for the Caching Service account (default: NT AUTHORITY\NETWORK SERVICE) and chose to store its configuration settings in an XML file which needs to be located in a file share (UNC server share: e.g.:\\CHRISTOPHE-PC\AppFabric).

Remark: You can also opt to store the configuration settings in an SQL Server database, but alas this is only allowed if you are part of a domain and not a workgroup. So I’m stuck with the XML option since I’m using Windows 7 Home Premium.

You can also change the default ports for the Cache node, but I used the default values.

Figure 3 – Configure AppFabric Cache Node.

Be sure to include the Windows firewall exceptions if needed!

Remark: Also check out Scott Hanselman’s article which contains more information about setting up AppFabric.

Top of page

Administration

When administrating AppFabric Caching you’ll have to do most of it using a command-line tool.

Figure 4 – Caching Administration Windows PowerShell

Run it as Administrator and type “Start-CacheCluster” to start the AppFabric Caching Service.

Figure 5 – Starting The Cache Cluster

Afterwards I changed the startup type of the service to automatic via the MMC Services add-in.

Figure 6 – Services

You can also download the AppFabric Caching Administration Tool by Ron Jacobs on CodePlex if you prefer a graphical user interface to perform most of the regular tasks when it comes to administrating the Microsoft Distributed Cache.

Top of page

Using The Cache in ASP.NET MVC

I created a blank solution in Visual Studio 2010 called AppFabric. The solution contains two projects, namely a class library (CGeers.Core) and a MVC 2 Web Application (MvcApplication).

Figure 7 – Solution Explorer

The CGeers.Core class library contains references to two assemblies from AppFabric.

Figure 8 – AppFabric Assemblies

I don’t want to directly use the AppFabric types in my MVC application so I added the following interface to the CGeers.Core library.

Listing 1 – ICacheProvider

public interface ICacheProvider
{
    void Add(string key, object value);
    void Add(string key, object value, TimeSpan timeout);
    object Get(string key);
    object this[string key] { get; set; }
    bool Remove(string key);
}

When I want to add / retrieve an object to / from the cache I use the methods of the static Cache type shown in Listing 2. Internally these methods use an implementation of the ICacheProvider interface and delegate all calls to that instance. The ICacheProvider instance is resolved using the ServiceLocator type provided by Unity 2.0.

Update 15.09.2011: Please check out the following StackOverflow question. It suggests a better approach of resolving an ICacheProvider implementation instead of using a static class as suggested here. I basically went for ease of use here (just use the Cache type), but it’s not very flexible if you want to change to another ICacheProvider. The approach suggested in the SO post also avoids having a dependency on the ServiceLocator and Cache types.

Listing 2 – Cache

public static class Cache
{
    private static readonly ICacheProvider CacheProvider;

    static Cache()
    {
        CacheProvider =
            (ICacheProvider) ServiceLocator.Current
                                    .GetInstance(typeof (ICacheProvider));
    }

    public static void Add(string key, object value)
    {
        CacheProvider.Add(key, value);
    }

    public static void Add(string key, object value, TimeSpan timeout)
    {
        CacheProvider.Add(key, value, timeout);
    }

    public static object Get(string key)
    {
        return CacheProvider[key];
    }

    public static bool Remove(string key)
    {
        return CacheProvider.Remove(key);
    }
}

Now we only need to create an ICacheProvider implementation for AppFabric. The following listing shows you how to do this.

Listing 3 – AppFabric CacheProvider Implementation

public class CacheProvider : ICacheProvider
{
    private static DataCacheFactory _factory;
    private static DataCache _cache;

    private static DataCache GetCache()
    {
        // ...
    }

    public void Add(string key, object value)
    {
        var cache = GetCache();
        cache.Add(key, value);
    }

    public void Add(string key, object value, TimeSpan timeout)
    {
        var cache = GetCache();
        cache.Add(key, value, timeout);
    }

    public object Get(string key)
    {
        var cache = GetCache();
        return cache.Get(key);
    }

    public object this[string key]
    {
        get { return this.Get(key); }
        set
        {
            var cache = GetCache();
            cache.Put(key, value);
        }
    }

    public bool Remove(string key)
    {
        var cache = GetCache();
        return cache.Remove(key);
    }
}

All of the methods are pretty straightforward. The Add(…), Remove(…)…etc. methods all use the DataCache class provided by AppFabric. The GetCache() method configures and sets up your cache.

Listing 4 – Configuring and Setting Up the Cache

private static DataCache GetCache()
{
    if (_cache != null) return _cache;

    // Cache host(s)
    var servers = new List<DataCacheServerEndpoint>(1)
                        {
                            new DataCacheServerEndpoint("localhost", 22233)
                        };

    // Configuration
    var configuration =
        new DataCacheFactoryConfiguration
            {
                Servers = servers,
                LocalCacheProperties =
                    new DataCacheLocalCacheProperties(1000,
                        new TimeSpan(0, 10, 0),
                        DataCacheLocalCacheInvalidationPolicy.TimeoutBased)
            };

    // Disable tracing to avoid informational / verbose messages on the web page
    DataCacheClientLogManager.ChangeLogLevel(TraceLevel.Off);

    _factory = new DataCacheFactory(configuration);
    _cache = _factory.GetCache("default");

    return _cache;
}

The code shown in Listing 4 is taken from the code provided by the Windows Server AppFabric Samples.

Instead of configuring your cache from code you can also move this to your application’s configuration file. Let’s move it to the Web.config file. Make sure your web application projects references the assemblies displayed in Figure 8.

Listing 5 – Web.config

<configSections>
  <section name="dataCacheClient"
            type="Microsoft.ApplicationServer.Caching.DataCacheClientSection,
                  Microsoft.ApplicationServer.Caching.Core, Version=1.0.0.0, 
                  Culture=neutral, PublicKeyToken=31bf3856ad364e35"
            allowLocation="true"
            allowDefinition="Everywhere"/>    
    
  <section name="unity" 
            type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, 
                  Microsoft.Practices.Unity.Configuration" />
</configSections>
  
<dataCacheClient>
  <localCache isEnabled="true" sync="TimeoutBased" objectCount="1000" ttlValue="600" />
  <hosts>
    <host name="localhost" cachePort="22233" />
  </hosts>
</dataCacheClient>

You need to to include the DataCacheClientSection configuration section so that your application can understand and parse the dataCacheClient node of your configuration file. In this node you setup all hosts that make up your cache cluster, configure local caching…etc. You can now reduce the code of Listing 4 to this:

Listing 6 – Configuring and Setting Up the Cache via Web.config

private static DataCache GetCache()
{
    if (_cache != null) return _cache;

    var configuration = new DataCacheFactoryConfiguration();
    _factory = new DataCacheFactory(configuration);
    _cache = _factory.GetCache("default");

    return _cache;
}

Add a reference to the CGeers.Core library from the MVC application and you are ready to use the AppFabric Caching service.

Listing 7 – Adding an Object to the Cache

var myIdentifier = (Guid?) Cache.Get("MyIdentifier");
if (myIdentifier == null)
{
    myIdentifier = Guid.NewGuid();
    Cache.Add("MyIdentifier", myIdentifier, new TimeSpan(0, 0, 30));
}
ViewData["MyIdentifier"] = myIdentifier;

Don’t forget to configure your Unity container so that the ServiceLocator type (see Listing 2) will find the AppFabric implementation of the ICacheProvider interface. You can do this from your Global.asax Application_Start() event handler.

Listing 8 – UnityContainer

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);

    var container = new UnityContainer();
    var section = (UnityConfigurationSection) ConfigurationManager.GetSection("unity");
    section.Configure(container, "defaultContainer");

    var serviceLocator = new UnityServiceLocator(container);
    ServiceLocator.SetLocatorProvider(() => serviceLocator);
}

Remark: The contents of the UnityContainer are configured in the Web.config. Download the source code for this article if you want to check it out.

Top of page

ASP.NET Session State Provider

In ASP.NET you have 4 options when choosing which provider to use for your session state, namely:

  • In-Process (default)
  • ASP.NET State Service
  • SQL Server Mode
  • Custom

AppFabric provides a custom session state provider that allows you to store your session state in the AppFabric cache. You only need to expand the configuration shown in Listing 5 with the following which needs to be placed within the system.web node.

Listing 9 – Session State Provider

<sessionState mode="Custom" customProvider="AppFabricCacheSessionStoreProvider">
  <providers>
    <add
      name="AppFabricCacheSessionStoreProvider"
      type="Microsoft.ApplicationServer.Caching.DataCacheSessionStoreProvider"
      cacheName="default"
      sharedId="MvcApplication"/>
  </providers>
</sessionState>

Voila, your session state is now maintained by Windows Server AppFabric. Check out the following MSDN article for more information about configuring an ASP.NET Session State Provider for AppFabric:

http://msdn.microsoft.com/en-us/library/ee790859.aspx

Top of page

Download

You can find the source code for this article on the Download page of this blog.

Any comments, questions, tips…etc. are always appreciated.

Top of page

About these ads

10 Responses to “Windows Server AppFabric Caching”


  1. [...] Great blog post with source code on how to use Velocity with an ASP.NET applicatoin http://cgeers.wordpress.com/2010/07/04/windows-server-appfabric-caching/ [...]


  2. [...] la nuova tecnologia di caching targata Microsoft: AppFabric. A riguardo potete leggervi questo interessante post che mostra le fasi di installazione, amministrazione e di sviluppo. This entry was posted in [...]

  3. Nasir Khan Says:

    I we would like to leverage usage of SharePoint object model and some SharePoint site initialization events with App fabric cache object model. The way ASP.NET sessions can be cached using App fabric cache. I would like to cache site collections data using some configuration steps and some SharePoint initialization events.

    Please let me know if you have any pointers, links on similar lines.

  4. Vijendra Kumar Says:

    Hi,

    I read your blogs about both NCache and Windows AppFabric. Can you please tell me which one is better and for what reason?

  5. Siva Says:

    Thank you so much for nice articles and for you patience to put forward the downloadable samples. I feel that your posts are quite self explanatory. Keep it up…

  6. Lee Says:

    @Vijendra Kumar:

    I’ll suggest you use NCache. it is well established and mature distributed cache provider and there are some important features which NCache is offering but they missing in AppFabric. (like dynamic clustering and quick failove with consistent data, change cluster configurations on the fly etc ) here is a good read which talks about the features of NCache which |AppFabric is not offering.

    http://distributedcaching.blog.com/2011/05/26/ncache-features-that-app-fabric-does-not-have/

  7. Maria Says:

    Hi
    The above example works great ..
    But ther’s one roadblock for me here which i often face..when i check for cache statistics, the size of the cache remains 0…which is not how it should be..Please suggest something

    • Christophe Says:

      Sounds like your items aren’t being added to the cache. Please check the health stats for the cache cluster. It might be in throttled state.


Comments are closed.

Follow

Get every new post delivered to your Inbox.

Join 343 other followers

%d bloggers like this: