AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=1794&pId=-1
Introducing Microsoft Velocity
page
by Andrea Colaci
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 24787/ 42

Overview

Velocity is a Microsoft project; in CTP2, its goal is to provide a distributed, performing and highly available cache to our applications. Velocity could be integrated in Web and Desktop applications as well. And thanks to a simple API, it is possible to perform basic operations like putting and getting managed objects from cache, and also more complex operations like locking and searching by several criteria.

One of the features that make Velocity an interesting project is High Availability. This is obtained creating and using a cache cluster, made of multiple servers that together run distributed cache service, transparently managing in-memory storage of our managed objects, their consistency, search and optionally the confinement in specific regions and servers and, in the case of sudden server failure, the redundancy by storing copies of our cached objects on secondary servers.

To better understand Velocity and compare it against existing cache frameworks, I have built this feature matrix.

Setting up cache cluster

The first step to start using Velocity is to create a Cache Cluster: a group of one or more servers on which the service responsible for providing distributed cache will run. To demonstrate Velocity's key features we will use 3 servers: one for storing cache configuration settings and two as cache servers, on which Velocity service will run after being installed.

Figure 1: Cache Cluster

When installing Velocity on a cache server, a cluster configuration storage location must be specified, configuration includes a list of servers that are part of the cluster, tcp ports used for communications between cache services running on every server and other specific settings related to named caches created later. Three storage types are available for storing Velocity settings: xml-based file, SQL Compact edition (.sdf) and SQL Server which is the only cluster-aware, fault tolerant one.

For this demo, I opted for the third choice because it is a nearly real-world scenario and is easier to inspect tables created behind the scenes by Velocity.

Figure 2: Cache host setup

Cluster configuration and administration is provided by Powershell console commands, well described and enlisted on MSDN documentation.

To start the cluster, launch Powershell (with Administrative privileges) from a cache server and type:

start-cachecluster

Figure 3: Starting the cluster from Powershell console

Though it is now possible to use default cache, we proceed by creating a named cache, typing:

new-cache -CacheName CatalogCache -Secondaries 1 -TTL 15

With this command, a cache named "CatalogCache" will be created, leveraging 2 servers, primary and secondary. After an object is stored in a cache, a second copy will be stored on a secondary server and kept consistent, cache duration is configured to 15 minutes. To obtain some statistics about the cache we just created, type:

get-cachestatistics

Figure 4: get-cache and get-cachestatistics console output

Demo overview

The application used in the demo represents an online electronics shop where customers can browse a simplified product catalog and can add products to their shopping cart. Now let us suppose that loading the catalog is such as long-running operation, querying several heterogeneous data sources. For these reasons a cache strategy is suitable between Data Access Layer and data sources. The catalog became a good candidate to be stored in cache, increasing the application responsiveness and avoiding database roundtrips.

Note: Although the techniques used in the demo are similar to many real world scenarios, these are not the recommended way to manage an online catalog; it is only a demo.

Setting up development environment and start using Velocity

To start using Velocity in our applications, just add references to the following assemblies, picking them from Velocity’s installation folder from one of the cache servers.

Figure 5

Then add the Velocity namespace: Using System.Data.Caching;.

Here is a code listing used to access the named cache created previously. You can see that an array of ServerEndPoint is created first, representing our cluster, and then a CacheFactory is used to create a CacheClient which can be used to put and get objects in cache back and forth.

Listing 1

//Declaring cluster's servers
ServerEndPoint[] servers = new ServerEndPoint[2];
servers[0] = new ServerEndPoint("SERVER1", 22233, "distributedCacheService");
servers[1] = new ServerEndPoint("SERVER2", 22233, "distributedCacheService");
            
//Creating cacheFactory
CacheFactory factory = new CacheFactory(servers, truefalse);
//Accessing named cache
Cache catalogCache = factory.GetCache("CatalogCache");
 
//Putting catalog into Velocity cache
catalogCache.Put("Catalog1", CatalogManager.GetCatalog("Catalog1"));

After putting the object in cache, it is then possible to retrieve it later.

Listing 2

//Getting catalog from Velocity cache
Catalog myCatalog = (Catalog)catalogCache.Get("Catalog1");

In the demo application, when the catalog is not in the cache, it is loaded from the database, once it is put in cache, the same catalog can be accessed from any web server in the farm. This is a different behavior from ASP.NET cache, in which every web server can access only its cache. You can look at the address bars in figure 5 and see that the catalog is browsed using 2 different servers, but the catalog is the same one loaded at the time displayed in the statistics box. This could happen because objects are not stored in the same AppDomain of the web application (as would happen using ASP.NET cache), but they are stored in Velocity cache which offer a unified view of memory of all servers in the cluster.

Figure 6: Same page from 2 different web servers, accessing the same Velocity cache

 Server 1

 Server 2

ASP.NET Integration

At this point, as you may guess, we will see how we can integrate Velocity in our ASP.NET applications, obtaining a valid option for centralized Session management to existing StateServer and SQL Server modes. With the former, we have all the benefits included in a centralized session that, thanks to a service running on a state server, can distribute and balance web requests on several web servers in the farm, managing sessions in a centralized and performing way.

In this scenario, all web servers rely on a single state server on which all sessions are maintained. If High Availability is a requirement, this would not be satisfied as a sudden failure of session server would cause the loss of all sessions.

A plausible alternative could be storing sessions on SQL Server database, but with it we should also accept the performance loss when accessing session data, at least 25% less.

Velocity aims to mitigate the weakness exposed by both StateServer and SQLServer modes, offering a Session Provider that emulates a distributed and redundant StateServer, using a cluster of servers running cache service.

To appreciate this feature, we must instruct our application to use Velocity's Session Provider, modifying web.config as explained in these three steps:

1) Declare dCacheClient and Fabric config sections:

Listing 3

<section name="dcacheClient" type="System.Data.Caching.DCacheClientSection, 
CacheBaseLibrary" allowLocation="true" allowDefinition="Everywhere"/>
<section name="fabric" type="System.Data.Fabric.Common.ConfigFile, FabricCommon" 
allowLocation="true" allowDefinition="Everywhere"/>

2) Configure dCacheClient section, adding available servers in the cluster and the behavior of cacheClient. Also configure the fabric section, declaring logging mechanisms that cacheClient will use:

Listing 4

<dcacheClient deployment="simple">
 <localCache isEnabled="true" sync="TTLBased" ttlValue="300"/>
 <hosts>
  <!--List of cache servers (cache cluster)  -->
  <host name="SERVER1" 
        cachePort="22233" 
        cacheHostName="DistributedCacheService"/>
   <host name="SERVER2" 
        cachePort="22233" 
        cacheHostName="DistributedCacheService"/>
 </hosts>
 </dcacheClient>
<fabric>
 <section name="logging" path="">
  <collection name="sinks" collectionType="list">
   <!--LOG SINK CONFIGURATION-->
   <!--defaultLevel Values:  -->
   <!--  -1 = no tracing -->
   <!--   0 = Errors only -->
   <!--   1 = Warnings and Errors only -->
   <!--   2 = Information, Warnings, Errors -->
   <!--   3 = Verbose (all event information)-->
   <customType className="System.Data.Fabric.Common.EventLogger,FabricCommon"
                sinkName="System.Data.Fabric.Common.ConsoleSink,FabricCommon" 
               sinkParam="" 
                defaultLevel="-1"/>
   <customType className="System.Data.Fabric.Common.EventLogger,FabricCommon"
                sinkName="System.Data.Fabric.Common.FileEventSink,FabricCommon"
                sinkParam="Dcache/dd-hh-mm" 
                defaultLevel="-1"/>
    <customType className="System.Data.Fabric.Common.EventLogger,FabricCommon"  
                sinkName="System.Data.Caching.ETWSink, CacheBaseLibrary" 
                sinkParam="" 
                defaultLevel="-1"/>
   </collection>
 </section>
</fabric>

3) Change sessionState Mode parameter, setting "Custom" and declare the Velocity Provider that will be used as Session Provider:

Listing 5

<sessionState mode="Custom" 
              customProvider="SessionStoreProvider" 
  cookieless="UseUri">
 <providers>
  <add name="SessionStoreProvider"      
        type="System.Data.Caching.SessionStoreProvider, ClientLibrary"/>
 </providers>
</sessionState>

To demonstrate the use of Velocity Session Provider, I have also set cookieless parameter to "UseUri" for convenience, to be able to access the same session data while switching from one server to another.

In the following images note that, from two different browsers, accessing the same session data from two different servers, we are able to get the same shopping cart content. This means that we are accessing a centralized session data, but we are also relying on a cluster of cache servers at the same time, on which Velocity is running, providing a performing, high available and easy to use cache.

Figure 7: Same page and session, from 2 different web servers. Notice the shopping cart on the right side.

 Server 1

 Server 2

References
Conclusion

In this overview, I demonstrated only a few features of Velocity cache framework, in particular the opportunity to use Velocity as distributed and redundant cache, that could be accessed either web or desktop applications as well, using the same API.

Once overcoming the initial setup and configuration phase, we can benefit of a performing, reliable and easy to use cache. Finally, with just few changes to web.config file, it was possible to integrate Velocity in a web application, leveraging its Session Provider seamlessly and implicitly obtaining all benefits.


Product Spotlight
Product Spotlight 

©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-29 10:21:29 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search