Command Query Responsibility Segregation, or CQRS for short, is an architectural pattern based on the idea of Command Query Separation, CQS. It’s a pattern currently advocated by people like Udi Dahan, Greg Young, Mark Nijhof and Pål Fossmo (see below for links and resources).
The background for CQRS is a mathematical theorem called the CAP Theorem put forward by Eric Brewer. It states that;
“You can have at most two of these properties for any shared-data system: Consistency, Availability, and tolerance of network Partitions.”
You can only get two out of three, which basically means that you have to choose between scalability and continuous consistent data. CQRS is an architectural approach that let’s you scale out and deliver high availability, but is a bit more relaxed on the consistency. Meaning that Consistency has to step aside for Availability and Scalability.
Wouldn’t inconsistent data be a bad thing and something we would really strive to avoid? Yes, it would – if data were to be permanently inconsistent. But as long as the data eventually becomes consistent, this is no longer such a bad thing.
After all; how long are data in a multiuser application 100% consistent anyway? Think about it; As soon as the data has left the database – or whatever storage you might have – and is heading up to the user’s screen, someone else could have updated or even deleted the records. The data can be inconsistent even before they hit the screen!
Making a clear separation of commands (writes) from queries (reads) in an application gives you the ability to better scale out the parts that turns out to be bottlenecks. In most applications there are far more reads than writes, and so scaling out the read part will for most scenarios give a performance boost.
Now, calling it ‘eventual consistency’ might sound like it will take ‘forever’ before data is consistent, but just as you can scale the command and query parts of the system, you can also scale out the transport mechanism between them.
The transport is typically some kind of queue, for instance MSMQ-based, and so the time before data is consistent is coherent to the speed of the transport. Throw in some more power on the queuing machinery, and you get more up-to-date data.
Further reading
Udi Dahan’s “Clarified CQRS” is a good and thorough intro to CQRS.
More introductory on CQRS and how it relates to DDD by Pål Fossmo here; Command and Query Responsibility Segregation (CQRS).
Greg Young gives some clarifications on CQS vs CQRS in "Command Query Separation?".
For some more practical samples check out Mark Nijhof’s blog post "CQRS à la Greg Young", were he introduces his demo app on CQRS and Event Sourcing.
Jonathan Oliver has a run-through of CQRS vs Active Record vs Traditional Domain Model in "DDDD: Why I Love CQRS"
If you’re in the mood for some more background material on Brewer’s CAP Theorem, Julian Browne has an excellent article called "Brewer's CAP Theorem – The cool aid Amazon and Ebay have been drinking".
And just when you’re all pumped up and high on CQRS; Read the “CQRS: Crack for architecture addicts” by Gary Shutler. It might get you down on the ground again. I might not agree with him, but he makes some valid points.
And of course, for all DDD-related topics; The Yahoo Group for Domain Driven Design. Lot’s of good discussion there – including CQRS.
2 comments:
The irony is I quite like the idea of CQRS. I just see the many examples out there as being very high complexity implementations of the idea. There are no examples of simple applications of the CQRS idea which is something I hope to rectify this year as I write a new system.
Good point. And it's something that I've been thinking a bit about myself too. There is however a bit of danger in trying to ’dumb down’ a CQRS solution. And that is the overwhelming plumbing such a solution need to have. It’s the demo syndrome I guess; if you make a solution to demonstrate why CQRS is a great thing, you need to make it complex. Using this kind of architecture in a less complex problem space would simply be overkill (or over-architctecting rather). But to demonstrate the how one would rather make a simpler solution, but then again; you might not see the point in using CQRS.
Anyway; I believe there’s always need for more sample code on this subject, and so I’m hoping to put something out in the upcoming weeks. First out is a demo on how to use a single WCF service as the gateway to the command handlers on the server side. Hopefully I’ll be able to build further on that and demonstrate the how of CQRS.
Thanks for you input!
Post a Comment