How to Keep MySQL and Redis in Sync: Practical Cache Consistency Patterns

This article explains why cache inconsistency occurs between MySQL and Redis, then walks through four concrete design patterns—delete‑then‑update, update‑then‑invalidate, read/write‑through, and write‑behind—detailing each step, trade‑offs, and failure scenarios to help engineers choose the most suitable approach.

Architect
Architect
Architect
How to Keep MySQL and Redis in Sync: Practical Cache Consistency Patterns

Cache Consistency Problem

MySQL provides durable relational storage, while Redis is used as an in‑memory cache to accelerate reads. When data is modified, the application must update both MySQL and Redis. Because the two systems are independent, the updates cannot be made atomically; a short time window exists where one succeeds and the other fails, especially under concurrent reads and writes. Distributed transactions could eliminate the window, but they are rarely adopted in practice due to complexity and performance cost.

Why Inconsistency Happens

In a write operation the sequence is:

Update MySQL.

Update or invalidate the Redis entry.

If the two steps are not tightly coupled, a client may read the stale value from Redis before the cache is invalidated, or may read an old value that was repopulated from MySQL after the cache entry was deleted but before the database write completed. This race condition is the root cause of cache inconsistency.

Four Cache‑Update Design Patterns

2.1 Delete‑Cache‑Then‑Update‑Database

Steps (illustrated in the diagram):

Client 1 initiates an update of data A.

Client 2 concurrently queries data A.

Client 1 deletes the Redis key for A.

Client 2 misses the cache, reads A from MySQL, and repopulates the cache.

Client 1 finally writes the new value of A to MySQL.

Result: Redis still holds the old value, producing a stale (dirty) cache entry. The pattern is discouraged because the window for stale data can be long under high concurrency.

2.2 Update‑Database‑Then‑Invalidate‑Cache (Cache‑Aside)

Steps (diagram shown):

Client 1 updates A in MySQL.

Client 2 reads A from Redis and receives the stale value.

Client 1 invalidates the Redis key for A.

Client 3 later queries Redis, gets a miss, reads the fresh value from MySQL, and repopulates the cache.

During the interval between the database write and the cache invalidation a stale read can occur, but the probability is low. This pattern provides eventual consistency with minimal impact on write latency.

2.3 Read/Write‑Through Pattern

In this design the application writes only to Redis; Redis synchronously forwards the write to MySQL (write‑through) and returns success. Reads are served from Redis (read‑through) and, if a miss occurs, Redis fetches from MySQL and caches the result.

Client 1 updates A in Redis; Redis writes A to MySQL and acknowledges.

Client 2 reads A from Redis and receives the fresh value.

Because the cache update and database write happen in the same transaction, inconsistency is virtually eliminated. The drawback is that Redis must be extended to support synchronous writes, which adds implementation complexity and may increase write latency.

2.4 Write‑Behind (Write‑Back) Pattern

Here the application updates only Redis; Redis queues the change and asynchronously persists it to MySQL.

Client 1 updates A in Redis and receives an immediate response.

Client 2 reads A from Redis and gets the updated value.

Redis later flushes A to MySQL in the background.

This pattern yields the lowest write latency and high read performance because the client never waits for MySQL. However, it sacrifices strong consistency: a brief period of stale reads is possible, and if Redis crashes before flushing, the update is lost.

Trade‑offs Summary

Delete‑then‑Update: Simple but prone to long‑lasting stale cache under concurrency.

Update‑then‑Invalidate (Cache‑Aside): Acceptable eventual consistency; low stale‑read probability.

Read/Write‑Through: Near‑zero inconsistency; requires cache modification and may increase write latency.

Write‑Behind: Best read/write latency; tolerates temporary inconsistency and risk of data loss.

Engineers should choose the pattern that aligns with their latency requirements, tolerance for stale data, and operational complexity.

Reference : developer.jdcloud.com/article/2776

Code example

相关阅读:
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendredismysqlCache Consistencycache-asideread-throughwrite-behind
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.