Installing, Configuring and Using Windows Server AppFabric and the "Velocity" Memory Cache in 10 minutes
A few weeks back I blogged about the Windows Server AppFabric launch (AppFabric is Microsoft's "Application Server") and a number of folks had questions about how to install and configure the "Velocity" memory cache. It used to be kind of confusing during the betas but it's really easy now that it's released.
Here's the comment:
Have you tried to setup a appfabric (velocity) instance ? I suggest you try & even do a blog post, maybe under the scenario of using it like a memcache for dasblog. I would love to know how to setup it up, it's crazy hard for what it is.
No problem, happy to help. I won't do it for dasblog, but I'll give you easy examples that'll take about 10 minutes.
Get and Install AppFabric
You can go to http://msdn.com/appfabric and download it directly or just do it with the Web Platform Installer.
Run the installer and select AppFabric Cache. If you're on Windows 7, you'll want to install the IIS 7 Manager for Remote Administration which is a little plugin that lets you manage remote IIS servers from your Windows 7 machine.
NOTE: You can also an automated/unattended installation as well via SETUP /i CACHINGSERVICE to just get caching.
The configuration tool will pop up, and walk you through a small wizard. You can setup AppFabric Hosting Services for Monitoring and Workflow Persistence, but since I'm just doing Caching, I'll skip it.
The Velocity Caching Service needs to know where to get its configuration and it can get it from one of two places - either a database or an XML file on a share. If you use the XML file on a share, you'll need to make sure the service account has access to the share, etc. I'll use a database. The config wizard can make it for you as well. Click Next then Finish up the configuration.
Configuring the Configuration Database...
Ok, let's start it up and poke around.
Start and Administer your Memory Cluster from PowerShell
Now what? Go to the Start Menu and type in Caching. You'll have an item called "Caching Administration Windows PowerShell." This is where you can connect to the cache, check out what's going on, make new caches, etc. Run it as Administrator.
If you type "get-command *cache*" you'll see all the different commands available for cache management. I typed start-cachecluster.
C:\> Start-CacheCluster
HostName : CachePort Service Name Service Status Version Info
-------------------- ------------ -------------- ------------
HANSELMAN-W500:22233 AppFabricCachingService UP 1 [1,1][1,1]
Cool, it's up and running. If you look in the config database (or the XML file if you chose that) you'll see that I have one machine in my memory cluster. I could have lots and lots, and if I had Windows Server Enterprise I would also have high-availability if one of the nodes went down.
I download the AppFabric Caching Samples and opened the CacheSampleWebApp in Visual Studio. Immediately we notice the two new references we don't usually see in a web application, Microsoft.ApplicationServer.Caching.Core and .Client.
Remember that for security everything is locked down by default, so you'll need to grant access to the cache for whatever user you'll be using to access it. I'm running as "ScottHa" so I'll run
Grant-CacheAllowedClientAccount scottha
...and you should do the same for whatever account your IIS is running as.
Use Your Memory Cache from ASP.NET
Remember that you can chop up your memory caches into logical buckets (partitions) and a memory cluster can serve more than one application, if you wanted.
Your cache can be hooked up in the web.config or from code (however you like). Here's a code example helper method where the sample does this manually. This data could come from wherever you like, you just need to tell it a machine to talk to and the portnumber. It'll automatically connect to the
Caches can also be partitioned. For example, I'm using a named cache called "default" but I could have multiple logically segmented areas like "shoppingcart" and "productcatalog" if I wanted.
using Microsoft.ApplicationServer.Caching;
using System.Collections.Generic;
public class CacheUtil
{
private static DataCacheFactory _factory = null;
private static DataCache _cache = null;
public static DataCache GetCache()
{
if (_cache != null)
return _cache;
//Define Array for 1 Cache Host
List<DataCacheServerEndpoint> servers = new List<DataCacheServerEndpoint>(1);
//Specify Cache Host Details
// Parameter 1 = host name
// Parameter 2 = cache port number
servers.Add(new DataCacheServerEndpoint("mymachine", 22233));
//Create cache configuration
DataCacheFactoryConfiguration configuration = new DataCacheFactoryConfiguration();
//Set the cache host(s)
configuration.Servers = servers;
//Set default properties for local cache (local cache disabled)
configuration.LocalCacheProperties = new DataCacheLocalCacheProperties();
//Disable tracing to avoid informational/verbose messages on the web page
DataCacheClientLogManager.ChangeLogLevel(System.Diagnostics.TraceLevel.Off);
//Pass configuration settings to cacheFactory constructor
_factory = new DataCacheFactory(configuration);
//Get reference to named cache called "default"
_cache = _factory.GetCache("default");
return _cache;
}
}
Once your cache is setup, it's trivial to use.
m_cache.Add(orderid, order);
and
Order order = (Order)m_cache.Get(orderid);
or updating an existing object:
m_cache.Put(orderid, order);
Check your Caching Statistics
So after adding a bunch of items to the cache, then requesting a bunch back I can go into PowerShell and see what's going on:
C:\> get-cache
CacheName [Host]
Regions
--------- ---------------
default [HANSELMAN-W500:22233]
Default_Region_0103(Primary)
C:\> Get-CacheStatistics default
Size : 2493
ItemCount : 5
RegionCount : 5
RequestCount : 17
MissCount : 3
You can use Performance Monitor as there is an imperial buttload of different Performance Counters Available. As I mentioned, you can make different partitions, like "default" or "poopypants" and check the stats on each of those separate, or the cache as a whole:
And of course, I can recycle my webserver, start it up again and fetch an order and it's still there. You've effectively got a big, partitionable distributed (and optionally highly available) hashtable across multiple machines.
Replacing ASP.NET Session State with AppFabric Caching
If you want, in ASP.NET 4 you can also swap out the default in-memory Session State Provider for AppFabric via your web.config. Here's an example web.config.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!--configSections must be the FIRST element -->
<configSections>
<!-- required to read the <dataCacheClient> element -->
<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"/>
</configSections>
<!-- cache client -->
<dataCacheClient>
<!-- cache host(s) -->
<hosts>
<host
name="CacheServer1"
cachePort="22233"/>
</hosts>
</dataCacheClient>
<system.web>
<sessionState mode="Custom" customProvider="AppFabricCacheSessionStoreProvider">
<providers>
<!-- specify the named cache for session data -->
<add
name="AppFabricCacheSessionStoreProvider"
type="Microsoft.ApplicationServer.Caching.DataCacheSessionStoreProvider"
cacheName="poopylands"
sharedId="MySharedApp"/>
</providers>
</sessionState>
</system.web>
</configuration>
Resources and Links
Here's a recent AppFabric caching slidedeck from Ron Jacobs I found useful. More links below. Microsoft Windows Server AppFabric Slides at SlideShare.
As with all things, a little abstraction goes a long way. If you have an existing caching strategy (via EntLib, or whatever) you can almost certainly swap out your internal storage for AppFabric Caching.
Related Links
- AppFabric on MSDN
- Configuring an ASP.NET Session State Provider (Windows Server AppFabric Caching)
- How to Create a Simple Enterprise Library Cache Manager Provider for Velocity
- AppFabric Caching Forums
- AppFabric "Velocity" Caching Documentation
- Windows Server AppFabric 1.0
- Windows Server 2003 Distributed Cache Client - while the memory service runs on Windows Server 2008, your existing apps running on Windows Server 2003 can use this cache client to access the Caching Service.
- Tracing and Caching for Entity Framework available on MSDN Code Gallery
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
Why is enterprise needed for high availability ? is it a licensing thing or does it use windows clustering services ?
All joking aside, great article.
@ed gillett> That seems like it'd be pretty easy to setup using Azure worker role instances, no? Or did you mean as a separate (and ideally cheaper...) service a la Azure Tables?
As a big nit-pick, a part of me dies inside when I still see non-generics like this:
Order order = (Order)m_cache.Get(orderid);
I mean, this was started after 2.0 came out, right?
For ASP.NET session state, the DataCacheSessionStoreProvider does not require ASP.NET 4. It works fine with clients running on 3.5 SP1 and will work on Windows Server 2003. Users will need to download the client libraries for Windows Server 2003, Windows Server AppFabric - Windows Server 2003 Distributed Cache Client.
You say
security everything is locked down by defaultOne area that I have yet to find solid documentation is regarding locking down the communication between clients and the servers, and between servers. We all know that AppFabric Caching (Velocity is much easier to say) just uses WCF and .NET TCP bindings. Is the communication between cache servers locked down by default? We store very sensitive patient health care information in session/cache. Having this information sync'ed between servers unencrypted goes against our security threat assessments. Links to sample configurations would be apprecicated. I will look at the Windows Server AppFabric Samples.
Checked out AppFabric this weekend, wrote a blog post about it:
http://cgeers.wordpress.com/2010/07/04/windows-server-appfabric-caching/
and will definitely be advocating its use at work tomorrow.
Windows Server AppFabric Caching Configuration Settings.
when configuring the place to store the Cache configs you can pick from UNC Share and Database. However, looks like the database storage is only available if the Velocity host is located inside a domain. Otherwise, in a DMZ environment, it won´t allow me to use the database. Is that correct? Is there a way to use the database to store the config when the host machine is not inside a domain?
Thanks!
Here is the webconfig area that I changed.
<sessionState mode="Custom" customProvider="AppFabricCacheSessionStoreProvider">
<providers>
<add name="AppFabricCacheSessionStoreProvider"
type=<b>"Microsoft.ApplicationServer.Caching.DataCacheSessionStoreProvider, Microsoft.ApplicationServer.Caching.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</b>
cacheName="default"
sharedId="MvcApplication"/>
</providers>
</sessionState>
One issue I have found is that the Microsoft.ApplicationServer.Caching.Client and Microsoft.ApplicationServer.Caching.Core assemblies are not visible in VS 2010 (x64) unless you browse for them in the System32/AppFabric directory, although when I check in the GAC the dll are there.
Is there a solution to that?
I've been trying to talk up AppFabric at work and get our Infrastructure people some information about Caching. The MSDN page however has a broken link on the "Getting Started" page. I sent a message to the feedback about the problem on July 1st and actually got a message back from the MSDN team saying they would fix the problem. The problem still exists 15 days later! For a product that has just released this is pretty sad. Hopefully you have more pull.
On the following page, click on the Getting Started link...
Windows Server AppFabric Caching Features
Yazid
http://androidyou.blogspot.com/2010/08/test-appfabric-on-windows-7.html
I was previously using Beta1 I believe. I've now upgraded to the release, and changed my config to use the updated namespaces. But now I get the below error message, with the type of the session state provider being highlighted in red:
ErrorCode<ERRCMC0003>:SubStatus<ES0001>:Error in client configuration file.
Below is my relevant configuration pieces (with the types being split on multiple lines, in reality they're on one line):
<section
name="dataCacheClient"
type="Microsoft.ApplicationServer.Caching.DataCacheClientSection,
Microsoft.ApplicationServer.Caching.Core,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<dataCacheClient deployment="routing">
<localCache isEnabled="false"/>
<hosts>
<host name="myhost" cachePort="22233"/>
</hosts>
</dataCacheClient>
<add
name="AppFabricCacheSessionStoreProvider"
type="Microsoft.ApplicationServer.Caching.DataCacheSessionStoreProvider,
Microsoft.ApplicationServer.Caching.Client,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
cacheName="default"/>
Any ideas as to what this means, I can't find any information.
Thanks,
James
cacheHostName="DistributedCacheService"attribute on the host that was causing the issue I believe.
I get an error on the line of code:
_cacheCatalog.Get (strKey, CATALOG_CACHE_REGION);
The error is : An item with the same key has already been added.
I can not understand why I have this error on a Get method "?
Thank you very much for your help
Soulaymane Bouyardane
I'm confused as to why there is a SQL Server config databas yet you have to pass in a list of all the cache hosts/servers when creating the DataCachFactoryConfiguration object in order to get the factory?
Wouldn't you just provide the details of the SQLServer config DB where all these hosts would be registered?
What am I missing?
Thanks
Installing this on IIS7 Server 2008 R2 now. Not in a domain (staging server) Neither is our webfarm. Man this is a bitch to install..
Some hints,
1) As earlier written, only XML, no SQL.
2) Not service accounts, you will have to create a user to run the Caching service, make sure this user has Access this computer from the network right. Otherwise it will just popup an error saying user does not have requested logon right.
3) The installer package downloaded (3 times) gave a this package is not for this machine (running 64bit sql2008 r2), the web platform installer suggested to install the 32bit version, so thats what i did and that worked.. (64bit frameworks of dotnet are installed, so not sure whats the problem here. I already installed this version on dev servers and laptops).
4) webplatform installer insists on installing the sql 2008 express service., I dont want that on my webserver since it will not use it (no domain).
5)Now I'm stuck on the network share it needs. Gave my created service user user full controll and access permission. But the installer says, access denied.. You will have to add your own account running the installer access permission to the share. I'm hoping to remove this after finishing the installer.
This feels so half finished... It does not give me the confidence to push it as our webfarm solution..
For now I had to disable security on client (web.config) and server:
Server, appfab powershell cmd: Set-CacheClusterSecurity -SecurityMode None -ProtectionLevel None
Client, web.config:
<!--appfabric cache client -->
<dataCacheClient>
<!-- cache host(s) -->
<hosts>
<host name="localhost" cachePort="22233"/>
</hosts>
<securityProperties mode="None" protectionLevel="None" /><!-- this is stopping sending security credentials to the caching service-->
</dataCacheClient>
Comments are closed.
I can't remember how many times I've mentioned 'Velocity' to clients recently (last year or so) but always with a caveat "it's still in beta/ctp". Now I can just go for it :)
If only Microsoft would separate the caching story from the cloud related initiatives and update the documentation so that words 'beta' are no longer scattered all over the Velocity documentation, I think a lot of people would gladly embrace this technology.