December 07, 2019

Part 17: Microservices (CQRS and Event Sourcing)

Event Sourcing
A shared database is not recommended in a microservices-based approach, because, if there is a change in one data model, then other services are also impacted. As part of microservices best practices, each microservice should have its own database.

Let's say you have Customer and Order microservices running in their seprate containers. While the Order service will take care of creating, deleting, updating, and retrieving order data, the Customer service will work with customer data.

There will be one-to-many relationship between a customer and order. Assume both tables are in a single database, a one-to-many relationship can easily established.

But the shared database is not recommended in microservices. Now, let's separate the Order and Customer database, which will be accessed by respective microservices. But in this scenario, the relationships among the tables cannot be established, as both tables are in separate databases.

To create/ update the order, the Customer microservice can pass the customer_id as a request parameter to the HTTP service of the Order microservice. But the limitation of this approach is that transaction management cannot be properly handled. If customer data is deleted, the corresponding order also has to be deleted for that customer.

Though we can resolve this by calling a delete service in the Order service, but the atomicity is not achievable in a straight forward way. To overcome this limitation, we need to integrate an event-driven architecture with our microservices components. But again the atomic updates between the database and publish events to the message queue cannot be handled easily.

The solution to avoid these limitations, is event-sourcing. In event-sourcing, any event triggered will be stored in an event store. There is no update or delete operations on the data, and every event generated will be stored as a record in the database. If there is a failure in the transaction, the failure event is added as a record in the database. This will have below advantages:
a). Solves atomicity issues.
b). Maintains history and audit of records.
c). Can be integrated with data analytics as historical records are maintained.

In short, Event Sourcing is a way of persisting application state by storing an immutable sequence of events. State changes are triggered to update application state as response to these events.

CQRS
CQRS is another design pattern used in microservices architecture, in this we split the application into two parts: Command-Side and Query-Side.

It will have a separate service, model, and database for insert operations in the database. This acts as a command layer and separate service, model, and database for query data that acts as a query layer.

The read database can store a denormalized model where databases like NoSQL (which is horizontally scalable) can be leveraged. The command layer is used for inserting data into a data store and the query layer is used for querying data from the data store.

Why this is required? In traditional data management systems, both commands and queries are executed against the same set of entities. CRUD operations are performed on a single datastore and the same entity/ object is accessed to handle both read and write operations. There are mainly 2 issues with having a single view for both read and write operations: (a). It introduces the risk of data dispute. (b). Managing permissions and security become complex as the same objects are exposed to both read and write operations.

CQRS resolve these issues because in CQRS a method can either change the state of the entity, or return the result, but not both.

-K Himaanshu Shuklaa..

No comments:

Post a Comment