At SpringOne2GX I saw Michael Ploed give a good talk on the subject “Building microservices with event sourcing and CQRS”. Here I’ll do a quick rundown of the two patterns (event sourcing and CQRS) and then some reflections related to microservices.
The Event sourcing pattern is, like Michael defined it, all about: “Event sourcing is an architectural pattern in which the state of the application is being determined by a sequence of events”. There are some important implications of that:
- The full history of events are stored and can be inspected or used for playback to restore system state to a given point in time.
- Events are typically stored in an object/document format, as opposed to being de-composed into a relational model. Note: In a traditional relational model, keeping historical records often takes quite a bit of work and being able to see what the state was at a particular point in time is often not possible, historical records are often kept on a per-table basis (typical for audit-logging).
- Events must be immutable and may never be deleted, or the system state can’t be re-built. Delete is to be implemented as an own event, that is appended to the event store.
- Running queries for current state against the stack of events would typically perform bad, since the application would have to rebuild/maintain the current state from all stored events. Mitigating this problem is up to our next pattern.
The Command Query Responsibility Segregation (CQRS) is basically a pattern for separating access to datastore in an application into different services for read and write operations. The major points of this being:
- possibility to scale read-parts separately from write-parts
- possibility to choose an appropriate datastore technique for read vs write and optimize for each case, for example: for a read-heavy database you might want to have the equivalent of a hevily de-normalized database (although it doesn’t have to be a classic SQL-databse)
If we let write-operations append to the event store and then let those events propagate asynchronously to a read optimized datastore (propagation via a messaging paradigm) we can have a solution that is scalable and have some nice features as pointed out above. Notice that the async propagation of data from write-to-read access introduced eventual consistency into the solution, but we can’t have it all, remember the CAP-theorem.
The Microservices connection
Both event-sourcing and CQRS have been around for some time so that’s not really new. What’s interesting in the microservice context is that some event-handling will most likely be needed to synchronize state between different microservices in any reasonably complex landscape and these patterns can be a useful combination. In a more traditional monolithic solution the need for synchronization would often be less, typically due to access to a large data-model all at once, sometimes paired with a codebase with loose internal boundaries for data access. If we look at the success stories listed in the beginning of the Microservices presentation, both Karma and SoundCloud use event-handling as vital parts in their architecture, although not exactly as above.
Note: the video recorded talk will show up on infoq.com later on, together with all the other talks from SpringOne2GX 2015.
Hjälp oss att nå ut med information genom att dela nyheter och artiklar i ditt nätverk.