Ensuring Consistency Between Redis Cache and MySQL Database: Patterns and Practical Solutions
This article explains how to maintain data consistency between Redis cache and MySQL database by describing strong, weak, and eventual consistency, three classic cache patterns (Cache‑Aside, Read‑Through/Write‑Through, Write‑Behind), and practical solutions such as delayed double deletion, retry mechanisms, and binlog‑based asynchronous eviction.
Preface
In April a friend interviewed at Meituan and was asked how to guarantee consistency when writing to both Redis and MySQL. This article explores how to answer that question.
Understanding Consistency
Consistency means keeping data identical across distributed nodes.
Strong consistency : The system returns exactly what was written; good user experience but may hurt performance.
Weak consistency : The system does not promise immediate visibility after a write, only that data will become consistent after some time (e.g., seconds).
Eventual consistency : A special case of weak consistency where the system guarantees that data will become consistent after a bounded period.
Three Classic Cache Patterns
Caching improves performance and reduces database load, but can cause data inconsistency. The three classic patterns are:
Cache‑Aside Pattern
Read‑Through / Write‑Through
Write‑Behind
Cache‑Aside Pattern
The Cache‑Aside (or bypass cache) pattern aims to minimize inconsistency between cache and database.
Read Flow
The read process works as follows:
Read from cache; if hit, return the data.
If cache miss, read from the database, store the result in cache, and return the response.
Write Flow
When updating, the database is updated first and then the related cache entry is deleted.
Update the database, then delete the cache entry.
Read‑Through / Write‑Through (Cache Penetration)
In this model the cache acts as the primary data store, and all reads/writes go through an abstract cache layer.
Read‑Through
The simplified flow:
Read from cache; if hit, return.
If miss, load from database, write to cache, then return.
Read‑Through essentially wraps Cache‑Aside with an additional cache‑provider layer, simplifying code and reducing load on the data source.
Write‑Through
On a write request, the abstract cache layer updates both the cache and the underlying database synchronously.
Write‑Behind (Asynchronous Cache Writes)
Write‑Behind also uses a cache provider, but updates the cache first and writes to the database asynchronously in batches. This reduces write latency but weakens consistency, making it unsuitable for systems that require strong consistency.
Should We Delete or Update the Cache on Writes?
Using Cache‑Aside, many wonder why the write flow deletes the cache instead of updating it. Deleting avoids the “dirty data” scenario where concurrent writes cause the cache to hold stale values.
Updating the cache can waste CPU if the value requires complex computation, and in write‑heavy, read‑light scenarios it may be inefficient.
In a Dual‑Write Scenario, Should We Operate the Database First or the Cache First?
Consider two concurrent requests A (write) and B (read). If the cache is deleted after the database update, the read may fetch stale data from the database and repopulate the cache with old values, causing inconsistency. Therefore, Cache‑Aside prefers updating the database first and then deleting the cache.
Can We Achieve Strong Consistency Between Database and Cache?
Absolute strong consistency is impossible due to the CAP theorem; caches belong to the AP side (high availability, partition tolerance). For workloads demanding strict consistency, caching is not recommended, though weak or eventual consistency can be achieved with proper techniques.
CAP theorem states that in a distributed system you can only have two of the three: Consistency, Availability, Partition tolerance.
Three Strategies to Ensure Consistency
Cache Delayed Double Deletion
Delete the cache, update the database, then after a short sleep (e.g., 1 second) delete the cache again. The sleep duration should cover the typical read latency plus a safety margin.
Cache Deletion Retry Mechanism
If the second deletion fails, place the key into a message queue and retry deletion until it succeeds.
Asynchronous Deletion via Binlog
Capture MySQL binlog changes (e.g., using Alibaba Canal), push them to a message queue, and upon acknowledgment delete the corresponding cache key, ensuring eventual consistency without invasive code changes.
References & Thanks
Concurrent environment: database first or cache first?
High‑concurrency: update database first or cache first?
Dilemma: delete cache then update DB or vice versa?
Three cache read/write strategies explained
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
