How SQLCacheDependency Synchronizes Distributed Cache with Database?

Distributed Caching has become a popular way of improving .NET application performance and scalability. That is why developers are caching more and more data in distributed cache. However along with this come a few challenges. One important challenge is to ensure that data in the cache is always synchronized with the database. This is because the cache is keeping a copy of the data that already exists in the database.

If you have multiple applications updating the same data in the database but not all of them have access to the distributed cache, you’ll end up with a situation where data in the cache is older and different than its counterpart in the database. And, while this may be okay for some reference type of data, it is definitely not acceptable for transactional data. Reference data is one that you read a lot but don’t modify very frequently (e.g. product catalog) while transactional data is something you read and modify frequently (e.g. customer or account data).

So, how do you ensure that in these situations, the distributed cache stays synchronized with the database? The answer is SqlCacheDependency. SqlCacheDependency is part of ASP.NET Cache (System.Web.Caching) and allows you to specify a dataset in the database with an SQL statement and then receive .NET event notifications from SQL Server 2005/2008 whenever your dataset is modified in the database.

Download NCache free trial - Extremely fast and scalable in-memory distributed cache

NCache has internally incorporated SqlCacheDependency for the purpose of synchronizing cache with SQL Server 2005/2008 or Oracle database. To you, NCache provides a similar interface called SqlDependency that allows you to specify an SQL statement representing one or more rows in a given table that make up your cached item. NCache then internally uses SqlCacheDependency to establish a link with the database against these rows.

So, if your data is updated in the database by one of your applications, SQL Server fires a .NET event notification which NCache catches and removes the corresponding item from the distributed cache. This resolves data inconsistency issue of having two different copies of the same data. This is because when your application wants the same data next time, it doesn’t find it in the cache and is forced to retrieve the latest copy from the database which it then caches as well. This way, NCache ensures that the data in the cache is always consistent with the data in the database.

Here is a source code example of using SqlDependency of NCache that internally uses SqlCacheDependency:


public class Program {

    // A standard Load method that loads a single row from database
    public Customer LoadCustomer(Customer cust)
    {
	String key = "Customer:CustomerID:" + cust.CustomerID;

	Customer cust2 = (Customer)NCache.Cache.Get(key);
	if (cust2 != null)
	   return cust2;

	CustomerFactory custFactory = new CustomerFactory();

	// Load a single customer from the database
	// SELECT * FROM Customers WHERE CustomerID = 'ALFKI'
	custFactory.Load(cust);

	// Create a SqlCacheDependency for this item
	CacheItem item = new CacheItem(cust);
	item.Dependency = SqlDependencyFactory(connectionString,
	    "SELECT CustomerID FROM Customers WHERE CustomerID = '"
		+ cust.CustomerID + "'");

	// Store item in the cache along with SqlCacheDependency
	NCache.Cache.Insert(key, item);
	return cust;
    }

    // A query method
    public List<Customer> FindCustomers(String city)
    {
	String key = "List<Customer>:City:" + city;
	List<Customer> custList = (List<Customer>)NCache.Cache.Get(key);
	if (custList != null)
	    return custList;

	CustomerFactory custFactory = new CustomerFactory();

	// Load a list of customers from database based on a criteria
	// SELECT * FROM Customers WHERE City = 'San Francisco'
	custList = custFactory.FindByCity(city);

	// Create a SqlCacheDependency for this list of customers
	CacheItem item = new CacheItem(custList);
	item.Dependency = SqlDependencyFactory.(connectionString,
	    "SELECT CustomerID FROM Customers WHERE City = '" + city + "'");

	// Store list of customers in the cache along with SqlCacheDependency
	NCache.Cache.Insert (key, item);
	return custList;
    }
}

In summary, SqlDependency feature of NCache allows you to synchronize cache with the database and maintain data integrity. You can now start caching all data without the fear of using stale data from the cache. And, of course, the more data you cache, the better your application performance and scalability becomes.

So, download a fully working 60-day trial of NCache Enterprise and try it out for yourself.

Download NCache Trial | NCache Details

Posted in ASP .NET performance, ASP.Net, ASP.NET Cache, Cache dependency, Distributed caching, SQL cache dependency | Tagged , , , | Leave a comment

How to Improve ASP.NET Performance with Distributed Caching?

If your ASP.NET application only has a few users, you probably don’t care how fast or slow it is and it is probably giving you pretty good performance anyway. But, as you add more load to your ASP.NET application, the chances are quite high that ASP.NET performance will drop significantly. It might even grind to a halt if enough load is put on it. And, ironically, all of that happens just when your business is seeing more activity so the impact is even greater.

ASP.NET today has become really popular for high traffic apps and it is now common to see 10-20 server load balanced web farms and in some cases even 50-100 server farms. So, in these situations, ASP.NET performance is even more sensitive issue to resolve.

Download NCache free trial - Extremely fast and scalable in-memory distributed cache

The main reason for ASP.NET performance drop as you increase load on it is your database which cannot handle larger loads the way your ASP.NET application web farm can. This is because you can add more servers to the ASP.NET web farm but you cannot do the same with your database.

So, in these situations, your best bet is to use a distributed cache like NCache. NCache is in-memory so it is much faster than the database. And, NCache builds a cluster of cache servers and you can grow the cluster linearly just like the web farm. As a result, with NCache, your ASP.NET performance remains great even under extreme transaction loads.

You can use NCache in two ways: 

1. ASP.NET Session State Storage

You can configure your ASP.NET application to store ASP.NET Session State in NCache instead of InProc, State Server, or SQL Server. Please note that no programming is needed here. You only modify web.config code as following:

  <sessionstate cookieless="false"
                     regenerateExpiredSessionId="true"
                     mode="Custom"
                     customProvider="NCacheSessionProvider"
                     timeout="20">
     <providers>
         <add name="NCacheSessionProvider"
	      type="Alachisoft.NCache.Web.SessionState.NSessionStoreProvider"
	      exceptionsEnabled="true" enableSessionLocking="true"
	      emptySessionWhenLocked="false"  sessionLockingRetry="-1"
	      sessionAppId="NCacheTest" useInProc="false" enableLogs="false"
	      cacheName="myReplicatedCache" writeExceptionsToEventLog="false"
	      AsyncSession="false"/>
     </providers>
   </sessionstate>

2. ASP.NET Application Data Cache

The other way is for you to cache application data in a distributed cache like NCache so the next time your ASP.NET application needs this data, it will find it in the cache. Here is a small code sample on how to cache application data:

using Alachisoft.NCache.Web.Caching;

      ...

      Cache cache = NCache.InitializeCache("myCache");

      // Create a key to lookup in the cache
      // The key for will be like “Employees:PK:1000”
      string key = "Employee:EmployeeId:" + emp.EmployeeId.ToString();
      Employee employee = (Employee)Cache[key];
      if (employee == null) {
            // item not found in the cache. load from db
            LoadEmployeeFromDb(employee);

            // Now, add it to the cache for future reference
            Cache.Insert(key, employee, null,
                         Cache.NoAbsoluteExpiration,
                         Cache.NoSlidingExpiration,
                         CacheItemPriority.Default, null );
        }

The more data you cache, the less you have to go to the database and the faster is your ASP.NET application performance.

Download NCache Trial | NCache Details

Posted in ASP .NET performance, ASP.NET Cache, Distributed caching | Tagged , | Leave a comment

How Cache Dependency Manages Data Relationships?

Distributed cache is becoming very popular because it is a powerful way to boost your application performance and scalability and handle extreme transaction load without slowing down. Both .NET and Java applications are using it more and more each day. 

But, one challenge people face with distributed cache is how to map and store relational data in a HashTable (key, value) pairing storage that a distributed cache is. Most caches today do not provide any mechanism to handle this. Today, I will discuss Cache Dependency which ASP.NET Cache provides and that NCache incorporated from day one. 

Download NCache free trial - Extremely fast and scalable in-memory distributed cache

Just like ASP.NET Cache, in NCache, Cache Dependency allows you to specify a dependency in the distributed cache between two cached items. Cached item A depends on cached item B. And, if B is ever updated or removed from the distributed cache, A is automatically removed. This ensures that if there is a referential integrity constraint between A and B in the database that it is also honored in the distributed cache. You can also specify cascading Cache Dependency where A depends on B and B depends on C. Then, if you update or remove C, A and B are both removed. Here is a brief example of Cache Dependency:
Cache Dependency lets you create one-to-one, one-to-many, and many-to-many relationships in the distributed cache. Here is how you would handle different scenarios: 

One-to-one relationship:

A has one-to-one with B. Add B without any Cache Dependency. Then, add A and specify a Cache Dependency for B. If A and B both have a mutual dependency, then when update B afterwards and specify a dependency on A. 

One-to-many relationship:

A has one-to-many with B. Add A first without any Cache Dependency. Then, add one or more B items and specify a Cache Dependency for the given A for all of them. This way, if A is updated or removed, all of B’s will be removed automatically by NCache. 

Many-to-many relationship:

A and B have many-to-many with each other. Add one or more A’s. Then, add one or more B’s and specify Cache Dependency for the appropriate A’s. Then, go back and update A’s to specify Cache Dependency on appropriate B’s. 

public void CreateDependencies(Cache cache)
{
   string keyB = "objectB-1000";
   ObjectB objB = new ObjectB();
   string keyA = "objectA-1000";
   ObjectA objA = new ObjectA();
    // “null” third argument means objB does not depend on anything
   _cache.Add(keyB, objB, null,
              Cache.NoAbsoluteExpiration,
              Cache.NoSlidingExpiration,
              CacheItemPriority.Default, null, null);
    // third argument specifies that objA depends on objB
   string[] ADependsOn = { keyB };
   _cache.Add(keyA, objA, new CacheDependency(null, ADependsOn),
              Cache.NoAbsoluteExpiration,
              Cache.NoSlidingExpiration,
              CacheItemPriority.Default, null, null);
    // Removing "objB" automatically removes “objA” as well
   _cache.Remove(keyB);
   _cache.Dispose();
}

So, NCache allows you to take advantage of Cache Dependency and specify data relationships in the distributed cache. Download a fully working 60-day trial of NCache Enterprise and try it out for yourself.  

Download NCache Trial | NCache Details

Posted in ASP .NET performance, ASP.NET Cache, Cache dependency, Distributed caching, SQL cache dependency | Tagged , , , | 4 Comments

When to use client cache with distributed caching

A distributed cache is essential for any application that demands fast performance during extreme transaction loads. An in-memory distributed cache is faster than a database. And, it can provide linear scalability in handling greater transaction loads because it can easily let you add more servers to the cache cluster that a database server cannot do.

Despite all these benefits, there is still one problem. In most cases a distributed cache is hosted on a set of dedicated cache servers across the network so your application has to make network trips to fetch any data. And, this is not as fast as accessing data locally and especially from within the application process. This is where client cache comes in handy.

Download NCache free trial - Extremely fast and scalable in-memory distributed cache

In NCache, a client cache keeps a connection open to the distributed cache cluster and receives event notifications from the cache cluster whenever client cache data changes there. A distributed cache cluster knows which data items are being kept in which client cache so event notifications are sent only the relevant client cache instead of broadcasting them to all client caches.

How does client cache work?

A client cache is nothing but a local cache on your web/application server but one that is aware of a distributed cache and is connected to it. Additionally, a client cache can either be in-process, meaning a client cache exists inside your application process, or out-of-process. This allows a client cache to deliver much faster read performance than even distributed cache and at the same time ensure that client cache data is always kept synchronized with the distributed cache.

ncache-client-cache

ncache-client-cache

However, a distributed cache notifies client cache asynchronously after it successfully updates data in the distributed cache cluster. This means that there is technically a small window of time (in milliseconds) during which some of the data in client cache is older than the distributed cache. Now, in most cases, this is perfectly acceptable to applications. But, in some cases, applications demand 100% accuracy of data.

So, to handle such situations, NCache provides a pessimistic synchronization model for client cache as well. In this model, every time the application tries to fetch anything from the client cache, the client cache first checks whether the distributed cache has a newer version of the same cached item. If it does, then the client cache fetches newer version from the distributed cache. Now, this trip to the distributed cache has its cost but it is still faster than fetching the cached item entirely from the distributed cache.

When to use a client cache?

So, having known all of this, the main question that comes to mind is when to use a client cache and when not to use it. Well, the answer is pretty straight forward. Use a client cache if you’re doing a lot more reads than writes and especially if you’re reading the same items over and over again. And, if you’re doing a lot of updates or at least as many updates as reads (e.g. in case of ASP.NET Session State or JSP Servlet Session storage in NCache) then don’t use a client cache because the updates are actually slower with a client cache because you’re updating two different caches now, the client cache and the distributed cache.

So, NCache allows you to take advantage of client cache with a distributed cache. Download a fully working 60-day trial of NCache Enterprise and try it out for yourself.

Download NCache Trial | NCache Details

Posted in ASP.Net, client cache, Distributed caching | Tagged , , | 1 Comment

Using ASP.NET Cache in Web Farms

ASP.NET has now become a really popular technology for web apps and more and more people are developing high traffic applications in it. And, to handle higher traffic, these ASP.NET apps are deployed in load balanced web farms where you can add more servers as your traffic load increases. So, it is very scalable except for one problem. 

And, that problem is the database and your data storage which cannot scale in the same fashion to handle the higher traffic loads. So, what you get very quickly is a bottleneck where your ASP.NET application slows down and can even grinds to a halt.  

Download NCache free trial - Extremely fast and scalable in-memory distributed cache

In such situations, data caching is an excellent way of resolving this database and data storage bottleneck. Caching allow you to cache application data close-by and reduce those expensive database trips.  

What is ASP.NET Cache?

ASP.NET Cache allows you to cache application data and is actually a fairly feature-rich cache including the following features:  

  • Expirations: Automatic absolute and sliding expirations
  • CacheDependency: To manage data relationships in the cache
  • SqlCacheDependency: To synchronize cache with database
  • Callbacks: To be notified when items are updated in cache

Here is some sample code showing ASP.NET Cache usage.  

using System.Web.Caching;

// Create a key to lookup in the cache
// The key for will be like “Employees:PK:1000”
string key = "Employee:EmployeeId:" + emp.EmployeeId.ToString();

Employee employee = (Employee)Cache[key];
if (employee == null) {
    // item not found in the cache. load from db
    LoadEmployeeFromDb(employee);

    // Now, add it to the cache for future reference
    Cache.Insert(key, employee, null,
                 Cache.NoAbsoluteExpiration,
                 Cache.NoSlidingExpiration,
                 CacheItemPriority.Default, null );
}

ASP.NET Cache Limitations in Web Farms

 Despite very useful caching features, ASP.NET Cache has some serious limitations. They are:  

  • Does not synchronize across server or worker processes: It does not synchronize across multiple servers or even multiple worker processes. So, you cannot use it in a web farm or even a web garden unless your data is read-only whereas you need to cache all kinds of data, including one that changes somewhat frequently.
  • Cache size limitation: You cannot grow the ASP.NET Cache to be more than what one ASP.NET worker process can contain. For 32-bit systems, this is 1GB and that includes app code as well. Even for 64-bit systems, the size cannot scale.

Use ASP.NET Cache Compatible Distributed Cache

The way to work around these limitations of ASP.NET Cache is to use a distributed cache like NCache for web farms. NCache provides the same features that ASP.NET Cache plus more. But, as a distributed cache, NCache easily synchronizes across multiple servers. Here are some benefits you get from NCache:  

  1. Scales transaction load very nicely: You can keep adding more cache servers to the cache cluster as your web farm grows from 2 to 200 servers. NCache never becomes a bottleneck in handling more traffic.
  2. Scales data storage nicely: As you add more cache servers, your cache storage capacity grows due to Partition Cache topology.
  3. Replicates data for reliability: You can ensure that no data loss occurs even if a server goes down because data is replicated to other servers.
  4. Dynamic self healing cache cluster: NCache provides 100% uptime through this. And, you can add or remove cache servers at runtime without stopping the cache or your application.

asp-net-cache-blog-figure1  

Well, if you have an ASP.NET application running in a web farm, take a look at NCache and see how it will help improve your application’s performance and scalability. Here are some useful links for NCache:  

 Download NCache Trial  |  NCache Details 

Posted in ASP.Net, ASP.NET Cache, Distributed caching, SQL cache dependency | Tagged , , , , , | 3 Comments

Configure ASP.NET Session State for Web Farms

There is absolutely no doubt about it. ASP.NET has come to age and a good majority of ASP.NET applications now are high traffic and mission-critical. That means you cannot afford unscheduled downtime of either the entire website or some of the servers where many users are getting bumped out. This is because these downtimes cost you dearly in lost revenue and a bad reputation that is hard to fix.

ASP.NET Session State storage if not handled correctly can cause unscheduled downtimes. Microsoft offers four storage options for ASP.NET Session State:

  • InProc: Sessions kept inside worker process
  • StateServer: Session kept in a separate process
  • SqlServer: Session kept in SQL Server
  • Custom: Session kept in a third-party custom store

Both InProc and StateServer don’t have the capability to replicate ASP.NET Session State to more than one server and therefore cause data loss if any web server goes down. In fact, if you have a single StateServer for the entire website and it goes down, you’re totally hosed because your entire website will go down.

Download NCache free trial - Extremely fast and scalable in-memory distributed cache

SqlServer is the third storage option for ASP.NET Session State and it does provide server redundancy and data replication because you can build a database cluster, either mirrored or load-balanced cluster.

But, it’s expensive to setup SQL Server clusters and there are cheaper and more viable alternatives available. Additionally, SQL Server (like all relational databases) was designed to store structured relational data and not BLOBs; whereas, ASP.NET Session State is stored in SQL Server as BLOBs. So, not only are the sessions slow to access but the database quickly becomes a bottleneck as you try to scale your application.

A considerably better alternative to all of this is to use the Custom storage option of ASP.NET Session State and use an in-memory distributed cache (NCache) as your ASP.NET Session State storage. NCache replicates sessions across multiple servers so if any one server goes down, there’s no loss of session data. NCache is also much faster to access than SQL Server because it is in-memory. Finally, NCache allows you to easily scale the cache cluster as your web farm size grows. Simply add more cache servers to the cluster so there is never a bottleneck.

And, best of all, there is no programming needed to use NCache for ASP.NET Session State storage. Simply modify your web.config to specify the following:

<assemblies>
    <add assembly=”Alachisoft.NCache.SessionStoreProvider,
                   Version=3.8.0.0, Culture=neutral,
                   PublicKeyToken=CFF5926ED6A53769″/
>
</assemblies>
<sessionState cookieless=”false” regenerateExpiredSessionId=”true” 
    mode=”Custom” customProvider=”NCacheSessionProvider”
    timeout=”20″>
    <providers>
            <add name=”NCacheSessionProvider”
type=”Alachisoft.NCache.Web.SessionState.NSessionStoreProvider”
                
 sessionAppId=”NCacheTest” enableLogs=”false”
                 cacheName=”myReplicatedCache”/>
    </providers>
</sessionState>

Well, if you have an ASP.NET application running in a web farm, take a look at NCache and see how it will improve your ASP.NET Session State storage. Here are some useful links for NCache:

Download NCache Trial  |  NCache Details

Posted in ASP .NET performance, ASP.Net, Distributed caching | Tagged , , | 1 Comment