Event Sourcing Overview
Event sourcing is an architectural approach for (typically but not necessarily always) synchronously receiving and subsequently asynchronously distributing data (events) within an architecture. Events, once received, are persisted in a data store unique to the receiving service.
Only (C)reate, (R)ead and (D)elete operations are allowed to be performed in the persistence tier, with deletes ideally being seldomly used. (U)pdates are never allowed on the persistence tier. The receiving system (“event generator” or “event producer”) is completely decoupled from the consumers of any events and all data transfer between producer and consumer is performed asynchronously with respect to the original transaction.
Many other event sourcing descriptions refer to the persistence tier or event store as an append-only store. The issue with disallowing deletes to the store is that the store grows to a rate that becomes unusable over time, even with the use of partitions within the store. A best practice is therefore to allow the event generator service to insert/create/append, clients to read where necessary, and some other service to summarize and delete as appropriate.
Events may be propagated from the event generator via a message bus to multiple consumers, or by direct access from consumers themselves to the data store. AKF partners prefers distribution to happen through messaging systems to reduce the number of accesses to the persistence tier of the event generator. We prefer an implementation consistent with our “smart end points, dumb pipes” pattern. https://akfpartners.com/growth-blog/architecture-principle-messaging-systems-smart-end-points-dumb-pipes
The diagram below depicts the rough approach for event sourcing.
- The event sourcing system (SA) receives transactions and writes an event to its persistence tier.
- Only inserts/appends (C)reates are allowed.
- A Propagator service takes events and publishes them to a dumb bus asynchronously from the original transaction to (SA).
- Clients, (SB) through (SN) read from the bus, adhering to the bus contract and protocol, and intelligently modify data to their needs.
- A Summarizer service “snapshots” or summarizes data and state where necessary and removes data from the persistence tier/journal to maximize speed of operations.
Some clients ask us why the data should be persisted in a store and subsequently propagated rather than immediately writing to a message bus. The answer is multi-fold:
- Persisting in a ledger format allows for durability of the message and subsequent replay if one or more clients don’t get the message or need the message again.
- The store serves as a mechanism by which point in time “views” (created through the “Summarizer” service) can be easily created and recreated.
- The store serves as a ledger for certain solutions, providing auditability and traceability of messages through the system.
Benefits of Event Sourcing
- Enables (but does not in itself create) the capability for isolation (microservices bulkheads https://akfpartners.com/growth-blog/bulkhead-pattern) between services and domains.
- Eliminates issues associated with conflicting updates, but at the cost of needing to handle certain ACID characteristics (e.g. Idempotency and Consistency) within the application/service.
- Enables ledger-like solutions where appropriate, as in the case of books of record such as accounting like systems.
- Leverages asynchronous interactions, increasing a solution’s response to highly elastic demand without complete failure.
- Low cost flexibility in changing data models – as the model is a “ledger” it never changes and consumers can modify their data models without impact to the primary data store.
- Can be very useful in solutions like CQRS without needing to rely on proprietary replication solutions found in many ACID and BASE persistence engines.
- Events are simple objects without relationships and the impedance problems that can sometimes occur due to complex relationships.
- Due to eliminating updates, writes are incredibly fast and comparatively low cost on nearly any data store.
Drawbacks to Event Sourcing
- Eventual Consistency – the asynchronous nature of event sourcing means that solutions are only “eventually consistent” and as a result it is difficult to use event sourcing in some scenarios without significant engineering work.
- Perceived Inconsistencies due to Race Conditions (e.g. stock pick, stock replacement scenario).
- Engineers need to handle idempotency for competing events. Consumers must not reapply updates that have already been received one time for the same initial operation.
How to Use Event Sourcing
- Create (Insert)/Read/Delete only – Do Not Update.
- Be wary of multiple producers and multiple consumers as it relates to consistency in multi-threaded solutions.
- Only extract information using an event-identifier. To determine current state, replay a series of events. Think “blockchain”.
- For very large objects/streams, consider using a consumer to store point in time state in another solution to eliminate the need for repeated and costly “replays”.
When to Use Event Sourcing
- Whenever data received in one location must be present in multiple other locations or domains and isolation/bulkheading/swimlaning is necessary for high availability. While there are other approaches to achieving proper isolation, event sourcing is a good candidate.
- Whenever data is used for multiple purposes and needs to be represented in various fashions or relational models.
- As an option to native replication capabilities as when implementing the CQRS pattern
When Not to Use Event Sourcing
- When the data a service uses need not be represented in other places, or a service’s data is only acted upon by that service - do not implement it as an event source.
- When the intellectual and engineering cost to implement event sourcing exceeds its value, consider using a similar model but without the append-only ledger approach.
AKF Partners helps companies build scalable, highly available, cost effective, low-latency, fast time to market products. Call us – we can help!