Daniel Ansari’s blog Random software musings

February 12, 2010

NHibernate caching solution for web farms

Filed under: NHibernate,Open Source — Tags: , , , — admin @ 11:08 am

If your application uses NHibernate in a web farm, there is already a second-level cache provider that you ought to be familiar with: NHibernate.Caches.SysCache2, which supports expiration based on SQL table or command-based dependencies.  Whilst this is a decent solution, it does cause your whole cache region to be invalidated when data changes in the table.

It may be more ideal for you to invalidate the cache on a per-object basis, i.e., if one web server in the farm receives a request that causes a cached object to change, the portion of the application running on that server should be able to expire that object from the cache of all other servers within that farm.

A technique that I have used somewhat successfully is a shared disk cache invalidation mechanism called FileSysCache, similar to the “File Update Model” discussed in this MSDN library article.  Unlike the technique in that article, however, ours does not suffer from the issues arising from SQL Server trying to access the file system.  Our method creates a zero-length file on the shared disk, together with a CacheDependency to that file, for each cacheable object.  It deletes that file when the cache is invalidated for that object.  Thus, any other servers holding a cached copy of that object will have a CacheDependency on the same file, and their cached copies will expire.

This happens behind the scenes for you as an application developer.  NHibernate will call the relevant methods in the caching provider; all you need to know is that to expire the object across the web farm, you just need to evict it from the second level cache, using:

session.Evict(obj)

To configure FileSysCache, put the following into your web.config:

  <configSections>
...
    <section name="filesyscache" type="NHibernate.Caches.FileSysCache.FileSysCacheSectionHandler, NHibernate.Caches.FileSysCache" />

and also:

  <filesyscache path="C:\Projects\NHibernate.Caches.FileSysCache.Tests\bin\Debug\Cache">
    <cache region="foo" expiration="500" priority="4" />
  </filesyscache>

I meant to make this post a few years ago, so I hope the information here is still relevant, and I hope it’s better late than never.

The code, including unit tests, may be found here.

12 Comments »

  1. Please share the source code link of this article

    Comment by Neelesh — March 31, 2010 @ 1:16 am

  2. The link to the source code is in the article.

    Comment by admin — March 31, 2010 @ 7:22 am

  3. Hi thanks for the reply.But this link does not open .It returns “page Not Found 404” error.

    Comment by Neelesh — April 1, 2010 @ 4:01 am

  4. My apologies, it was working from the home page, but not from the individual article page – it’s fixed now.

    Comment by admin — April 1, 2010 @ 7:56 am

  5. hi,

    I am trying to implement FileSyscache, I have a doubt here, in the following

    In a web farm, could you please share how this path should be implemented? Is it like we have to create a shared location for all the servers in Web Farm and set this path to that shared folder?

    Or we need to define this path poining so some local folder in each individual server’s web.config

    Hope I am able to explain

    Comment by Pab — April 16, 2010 @ 1:09 am

  6. I am try to ask about this path:

    filesyscache path=”C:\Projects\NHibernate.Caches.FileSysCache.Tests\bin\Debug\Cache”

    Comment by Pab — April 16, 2010 @ 1:11 am

  7. Hi could you please let us know what should be the path may be in:
    filesyscache path=”C:\Projects\NHibernate.Caches.FileSysCache.Tests\bin\Debug\Cache

    web farm. In the web.config of each server.

    Comment by pabmohan — April 18, 2010 @ 10:06 am

  8. Hi Pab, that’s correct, the path is for a shared drive that all the servers can access.

    Comment by admin — April 21, 2010 @ 3:09 pm

  9. Hello Daniel… looking for some insight or ideas on what an issue might be. We are running a webfarm of up to 8 servers on an older .net 2.0 project. Using Nhibernate 1.2.0xx. We have installed the FileSysCache, Syscache and Nhibernate dlls into our bin folders. We shared a directory out to the 8 servers as in “\\server\SharedcacheFolder” in our web.config. The issue we are encountering is that in Pre prod on two servers we don’t get ANY errors. On our prod using 4 servers, we get the following ‘You may not dereference an collection with cascade=”all-delete-orphan”‘. My question as per Pab is once again to confirm.. you should set your — filesyscache path=”\\server\sharedCacheFolder”/–. We are scratching our heads trying to look for ideas. Is it an issue that we are using the same sharedcachefolder for both PreProd and Prod? Thanks for any ideas.

    Comment by Mac — January 25, 2012 @ 12:02 pm

  10. Hi Mac, the way you’ve set your path appears correct. It looks like the problem might be with the NH mapping or the data itself.

    Are you sure the DB schema match exactly? Is it possible that the data in pre-prod is different and so the problem doesn’t surface in that environment?

    What if you make a small test app that won’t affect your main prod application, so that you can verify that FileSysCache works in prod?

    Comment by admin — January 25, 2012 @ 12:27 pm

  11. Hi Daniel. We spoke too soon wrt to the Pre Prod enviro. It is also failing. An interesting note is that when we inherited this issue we noted that the lazy setting was set to “false” in the mappings. As the hibernate was failing already we changed it to “true”. This has aggravated the situation. Now we get failure even without the filesyscache running. We are down to assuming it is a code bug of some type.

    Comment by Mac — January 26, 2012 @ 11:57 am

  12. Good luck finding and quashing the bug quickly. Please drop me a note later on and let me know how FileSysCache is working out for you.

    Comment by admin — January 26, 2012 @ 4:34 pm

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress