POSTS
Eventually Consistent Pattern
- 5 minutes read - 918 wordsI published an architecture in the two-part series which can be perfect for Digital Transformations. And to become fast-paced we decompose big monoliths to individual smaller microservices. That’s given and we can’t go back on that as there are a lot of accruals. But we also introduced some complexities too. One of them is Data access as it has become much more complex when you move to a microservices architecture. If multiple services were accessing the same data, schema updates would require coordinated updates to all the services. This would break the microservice lifecycle autonomy.
But distributed data structures mean that you can’t make a single ACID transaction across microservices. This, in turn, means you must use eventual consistency when a business process spans multiple microservices.
So if you need a highly concomitant, scalable and available application then you need to think eventual consistency. Otherwise ready to spend big bucks.
So what is Eventual Consistency?
By the book, Eventual consistency is a weak consistency model used in distributed computing to achieve high availability that informally guarantees that, if no new updates are made to a given data item, eventually all accesses to that item will return the last updated value.
And you agree or not Its reality now. Be it google search results, Bank wire transfers or recommendation engines. And above all DNS, Its the most popular system that implements eventual consistency.
Everything highly available/scalable is eventually consistent as transactional consistency would be merely impossible to obtain over a large network.
CAP explains it well
CAP Theorem is a concept that a distributed database system can only have 2 of the 3: Consistency, Availability and Partition Tolerance.
Consistency: Every read receives the most recent write or an error.
Availability: Every request receives a (non-error) response, without the guarantee that it contains the most recent write.
Partition tolerance: The system continues to operate despite an arbitrary number of messages being dropped (or delayed) by the network between nodes.
When a network partition failure happens should we decide to 1. Cancel the operation and thus decrease the availability but ensure consistency. 2. Proceed with the operation and thus provide availability but risk inconsistency.
So Chose what?
No distributed system is safe from network failures, thus network partitioning generally has to be tolerated. In the presence of a partition, one is then left with two options: consistency or availability.
Most of the business flows prefer availability over consistency. Data inconsistency in large-scale reliable distributed systems has to be tolerated for two reasons: improving read and write performance under highly concurrent conditions, and handling partition cases where a majority model would render part of the system unavailable even though the nodes are up and running.
So How to Implement it?
Ask yourself What would Users do?
Whether or not inconsistencies are acceptable depends on the client’s application. But In all cases, we need to be aware that consistency guarantees are provided by the storage systems and need to take that into account when developing applications.
A specific popular case is a Web site or mobile app in which we can have the notion of user-perceived consistency. In this scenario, the inconsistency window needs to be smaller than the time expected for the customer to return for the next page load. This allows for updates to propagate through the system before the next read is expected.
How will it help?
Let’s play out Scenarios.
If you want Strong Consistency then wait for backend, then update. Pros:
- Simple Implementation
- All Front End data is persisted
It comes with a high cost of
- Feedback for the user is delayed – Performance Issues.
- Failure of this ACID transaction causes usability frustration as they keep receiving errors.
- No Offline modes.
- No Subscription-based models.
- The high cost of scalability
Now let’s see if you apply the lens of Eventual Consistency i.e. Update, then wait for the backend. You can take another approach to provide as fast feedback for an end-user as possible. You can update your front-end and then wait for the backend to see whether an action succeeds or not. This way your users get the most immediate feedback as possible. Pros:
- It makes your front-end as responsive as possible.
- It makes communication with the backend more flexible.
- It is easy to make your app working offline.
- It makes your front-end code richer and smarter based on user actions.
- It’s easier to make your commands ‘pure’ based on the CQRS pattern.
- You can reduce the overhead of your backend code.
There are some expenses for this too
- Implementation is a little harder as you need to be able to
- You need to modify your backend to match this architecture
The conclusion is Decisions you can make to handle the effects of user actions can have major consequences on consistency design.
Let’s walk through an Example
A user’s favorites application.
Captures CRUD operations for Users’ favorites. i.e. Create, Read, Update and Delete. I looked at the business flows and carved out the user’s perceived consistency. Users can favorite an item while browsing through the catalog. But doesn’t need a strong consistency to check of favorites are captured or not. Even if they want to, then the same partition (within the front end) consistency is sufficient. This applies to update and delete as well.
Read is consistent in the network partition. As we have the cache to store the value.
Connect with Me
If you are interested for a conversation or a chat. Please reach me on my linkedin.
- Technology
- Architecture
- Digital Transformations
- Well-Architected Framework Lens
- Eventually Consistent