Setting Up Velocity (Distributed Cache)
As I previously wrote, Velocity is Microsoft’s entry into Distributed Caching. It is currently in its first public CTP, so there are certainly going to be some rough spots. The documentation is pretty good, but setting it up and using it the first time required some trial and error. Here is a quick overview on getting it Velocity setup and and using the API.
First, grab the CTP bits and run the MSI.
As part of the install process, it is going to ask you to create a cache host configuration. I just created a folder called cache and named it Sample:
Next, execute the Velocity administration tool (should be a short-cut on your desktop). This is a command line tool. Type “start cluster” to get things going.
Next, create a new VS.NET 2008 project and add references to following .dlls from the Program Files\Microsoft Distributed Cache folder: CacheBaseLibrary.dll, ClientLibrary.dll, FabricCommon.dll, CASBase.dll, and CASClient.dll.
You will also need to add an app.config (or web.config) file to your project with the following (you can get this from the docs as well). You will also need to update the name attribute under dacheClient/hosts/host to include your machine name. The setup summary documentation was not clear about this.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="dcacheClient"
type="System.Configuration.IgnoreSectionHandler"
allowLocation="true" allowDefinition="Everywhere"/>
<section name="fabric"
type="System.Fabric.Common.ConfigFile, FabricCommon"
allowLocation="true" allowDefinition="Everywhere"/>
</configSections>
<dcacheClient deployment="simple" localCache="false">
<hosts>
<!--List of hosts -->
<host name="YOUR_MACHINE_NAME_HERE"
cachePort="22233"
cacheHostName="DistributedCacheService" />
</hosts>
</dcacheClient>
<fabric>
<section name="logging" path="">
<collection name="sinks" collectionType="list">
<customType
className="System.Fabric.Common.EventLogger,FabricCommon"
sinkName="System.Fabric.Common.ConsoleSink,FabricCommon"
sinkParam="" defaultLevel="-1"/>
<customType
className="System.Fabric.Common.EventLogger,FabricCommon"
sinkName="System.Fabric.Common.FileEventSink,FabricCommon"
sinkParam="CacheClientLog" defaultLevel="1"/>
<customType
className="System.Fabric.Common.EventLogger,FabricCommon"
sinkName="System.Data.Caching.ETWSink, CacheBaseLibrary"
sinkParam="" defaultLevel="-1" />
</collection>
</section>
</fabric>
</configuration>
Now, we are just about ready to finally write some code. But before we proceed, there is one more thing we need to look up, the name of the cache. This is the part the tripped me up the most.
The basic example in the documentation looks like this:
using System.Data.Caching;
CacheFactory CacheCluster1 = new CacheFactory();
Cache Cache1 = CacheCluster1.GetCache("Cache1");
Cache1.Add("cachedStringKey1","This string will be stored in cache");
I had wrongfully assumed the cacheCluster1.GetCache(“Cache1”) call was referencing the name attribute we set above. This was concerning for a couple of reasons:
- It did not work. :)
- I didn’t like the idea of having to reference a specific machine.
The good news is #2 is not the case and reading through some of the documentation helped clear this up. The parameter that passed in GetCache is the name of the cache we are requesting. This is necessary since each host can support multiple caches.
It turns out the default cache name is “default” (go figure). To find this value you need to go back to admin command line tool and enter “list cache”
It also turns out, there is a static helper method which will supply the default cache name for you, so out of the box you can just ignore it (same goes for Region).
All the objects we need to access are in the System.Data.Caching namespace.
Here is the quick sample code:
using System;
using System.Data.Caching;
namespace CacheDemo
{
class Program
{
static void Main(string[] args)
{
var cf = new CacheFactory();
var cache = cf.GetCache(Cache.DefaultCache);
var s = cache["sample"] as Sample;
Console.WriteLine(s == null);
s = new Sample() {Test = "Hello World"};
cache.Put("sample", s);
s = cache["sample"] as Sample;
Console.WriteLine(s == null);
Console.WriteLine(s != null ? s.Test : "I am null");
Console.ReadLine();
}
}
[Serializable]
public class Sample
{
public string Test { get; set; }
}
}
In the code above, we create a new instance of the CacheFactory and then get a reference to the default cache. From there, it should look very similar to using the HttpCache with one exception, cache.Put. Similar to Memecached, Velocity supports the concept of Add’s and Put’s. The biggest difference between the two is Add will throw an exception if the given key already exists. If you use Put and the key does not exist, the object will be added. On the other hand, if the key already exists, Put will replace the object with he newer one.
There is a lot more to Velocity than what I covered above. Just browsing the API there appears to be options for locking and versioning objects as well. As I previously mentioned, I am on the fence if this is a good thing, especially for the types of sites and applications I tend to build. But if you need this kind of object management, Velocity might fit the bill for you.
Feel free to leave a comment if I missed a step or you need more clarification.
Similar Posts
-
You've been kicked (a good thing) - Trackback from DotNetKicks.com
-
Havok, ya disponible gratuitamente : El motor de físicas más empleado en el mundo de los videojuegos
-
Web Create a Nice, Lightweight JavaScript Tooltip Setting Up Velocity (Distributed Cache) .NET ANTS Performance
-
Pingback from Reflective Perspective - Chris Alcock » The Morning Brew #108
-
Setting Up Velocity (Distributed Cache) ...
-
Enjoying cup of Starbucks and Deep Purple Live in Stockholm 1970 (via Zune marketplace). WCF/WF My good
-
h2.entry-title { font-size: 1.1em; clear: left; } ul.hfeed { list-style-type: none; } li.xfolkentry


Comments
Jake Good on on 6.04.2008 at 10:07 AM
Do we know if it's marshalling? How complex can we get with objects we put in?
Scott Watermasysk on on 6.04.2008 at 10:17 AM
@Jake, not sure. The overview said "serializable CLR objects". My guess is it using WCF, so I think it will be rather flexible and have minimal constraints (although performance will decrease with object complexity).
David L. Penton on on 6.04.2008 at 11:37 AM
FYI: Memcached has a StoreMode enum - Add (store the data only if it doesn't already have data for a key), Replace (store the data only if the server does already have data for a key) and Set (store the data and overwrite it if it already exists).
Aaron on on 6.04.2008 at 11:41 AM
I posted my trial-and-error walk-thru last night for ASP.NET. I had a few troubles on Vista.
(The "default" name is in one of the configuration files in the initial directory you specified when Velocity was first installed.)
I'm glad to see that they have released this ... it's needed to help round-out the enterprise-ness of ASP.NET for larger scale web applications (and web services).
It may not be as good as some 3rd party products, but it is likely good enough.
Dan Ciruli on on 6.13.2008 at 6:37 PM
One thing I was troubled by was that you have to put enumerate the cache servers in the app.config file. I'm not sure what this means, exactly: if I add a server to my cache cluster, I have to modify the app.config of every app that uses the cache.
Also, it seems I won't have the ability to configure my app dynamically -- I'll have to know at app startup time where my cluster is, what servers are in it, etc. I won't be able to have my user "select" a cluster and point at it.
Still, I'm excited about the technology.