Saturday, April 2, 2011

Adventures with RavenDB

RavenDB (http://ravendb.net/) is an interesting beast - not quite at the vanguard of the 'no-SQL' movement, but an easy to deploy and use no-sql document database for Microsoft shops. It's also lighter on features when compared to its more mature counterparts, such as MongoDB, CouchDB et al, but its LINQ provider is a construct of relative beauty and the simple deployment in IIS is a boon.

I'm employing it in a very specific way for a project I'm working on. In essence, I have a WCF service that acts as the definitive configuration source for a range of distributed applications (web, windows services, fat clients), centralizing the management of configuration, some of which is shared. So, all in all, a reasonable concept (similar to Microsofts Configuration service, but far better). All of these applications depend entirely on the configuration service to serve their configuration on demand - failure to do so renders the application unusable - for example, enterprise library configuration is communicated by this mechanism.

The initial scheme has a set of XML documents, one per WCF server in the cluster, deployed with the services as a single unit (via web deploy). This is obviously quite beneficial in terms of redundancy - a WCF server can be removed from the cluster (for maintenance as a single example) and it makes no difference to the dependent configuration clients (the applications) - each WCF server having a private copy of the configuration documents and so independent.

Redundancy is all well and good, but what happens when the configuration needs updating in real time? Obviously each XML document(s) in the cluster needs to be modified - which is rather crude and inefficient when there are n machines in existence and also means there is a temporal window where the configuration service may respond with different results depending on the machine servicing the request. I looked at using DFS to support in place 'shared' editing, but it did not hold much appeal.

So, I could have reverted to the Microsoft configuration service approach, using a SQL server database, in which case I could take advantage of clustering also. But the applications want impossibly high availability - and in a fail over situation, there is a latency (certainly in my case) which could lead to unexpected application failures.

Thus enters RavenDB. It's lightweight, and I decided I could deploy a set of replicating instances in the WCF service cluster, in a multi master configuration. And it works well - at least in my current development tests; deployment to production is a little way off (and there is the small matter of RavenDB licenses, as my project is not open source).

So what do I get from this arrangement:
  • A simple persistence model (JSON based) for configuration documents
  • Per machine redundancy
  • Very high performance
  • Versioning and Replication 'bundles'
The idea appealed initially when I realised that I was of course dealing with XML documents to house my configuration, and at run time they were parsed and converted into host/application specific configuration sets. When you see them (as they are) in this light, the choice of a document database becomes relatively obvious. Sure, using SQL server was a viable option, but there were constraints for me that meant a document database was a superior choice.

I have a few issues with the current RavenDB conflict resolution approach, but nothing I haven't been able to work around.

As a final gesture to availability, the configuration service utilises a'provider' model. There are two providers therefore; one RavenDB flavoured, one the old XML document style. At run time a provider factory serves the duly configured provider, and has policies that can be associated with the factory to allow 'fall back' to a secondary option if the primary provider fails in execution. In my case, this means that the RavenDB provider is the primary, the XML document provider the secondary.

No comments: