CQRS (Command Query Responsibility Segregation) is a pattern where a different system is used to update information, than the system that reads it. It allows for scalability and high throughput. At Voxxed Days Bristol, Lorenzo Nicora will explain Event Sourcing and CQRS, when to use it, and when not to use it.
We asked Lorenzo how you manage a CQRS system, and when you would need it.
In CQRS, how do you manage the reads and writes so that, on reading, the data is the most up to date version?
It depends on the reason for adopting a CQRS architecture.
If you are separating reads from writes only for optimising different read use cases, and your system does not require high-throughput of writes or scaling, it is entirely feasible to write synchronously. This guarantees that you are always reading the latest state. A common misconception is that CQRS necessarily requires writing asynchronously.
If your goal is different, you probably have to write asynchronously and, in this case, the story is completely different. CQRS and Event Sourcing are efficient at managing the state across a distributed system, and for achieving scalability and high availability. But to scale, you need to abandon the idea of writing synchronously: synchronous operations are the worst enemy of scalability.
Propagating the information takes time. As soon as you drop synchronisation, you lose the concept of a global, current state. Maybe we are talking about a delay of milliseconds or even microseconds. You may adopt techniques to reduce it, as in-memory copies of the state, locally synchronised with writes. But it is always a compromise between consistency, performance and availability. Your reads will be only eventually consistent with writes and across the system.
When should CQRS and Event Sourcing be used?
Event Sourcing is very useful for handling high-throughput writes, scaling out your system and distributing your data efficiently. To scale out, you have to abandon synchronous operations, transactions and accept that you will live in an eventually consistent world.
Event Sourcing works very well both for distributing data and for handling eventual business consistency (talking about business consistency, here, not database consistency). Using Event Sourcing implies using some form of CQRS. At least, if you want to read your data back, eventually.
I understand this is not in line with the mainstream point of view of Event Sourcing. This considers as main drivers the ability to build audit logs, multiple view models and eventual business consistency by corrective events.
These are all positive effects. But Event Sourcing dramatically increases the complexity of your system. You should consider other possible alternatives if your requirement is, for example, building an audit log.
Are there any frameworks or implementations that are easy to get started with?
There are many frameworks around. Most of them are based on DDD concepts, like Axon.
The overlapping between modern DDD and Event Sourcing is another common misconception. I may mention Concursus, developed by some colleagues of mine at OpenCredo, that use a different approach optimised for the IoT and big-data world.
But Greg Young, who coined the term “CQRS”, once said: “Don’t write a CQRS framework!”.
I kind of agree with Greg. I think the Event Store (only a part of a complete Event Sourcing/CQRS system) may be generalised. The rest of the implementation, in particular projecting the state out of Events, depends too much on the particular use case, and you often end up re-inventing the Actor Model in the attempt to generalise it.
What are the most important lessons you’ve used, implementing CQRS and Event Sourcing?
One important lesson is to remember that you will eventually have to read the data you are writing.
It may sound obvious, but it’s easy to design a system only around writes, especially when they are your primary performance goal.
In a relational, normalised persistence system this may cause slightly underperforming reads. In an event-sourced system, you may end up with an entirely unusable system.
Consider your most important read use cases and design the “Q” side of your CQRS system from the beginning.
For more, see Lorenzo’s talk explaining CQRS and Event Sourcing at Voxxed Days Bristol.