How to Keep Cache and Database Consistent: Strategies, Pitfalls, and Best Practices
This article explains why cache‑database consistency is a classic challenge, compares common update‑then‑delete patterns, analyzes concurrency and master‑slave delay issues, and recommends reliable solutions such as asynchronous retries with message queues or binlog subscription to achieve eventual consistency.
Introducing Cache to Improve Performance
When traffic is low, direct database reads and writes are sufficient, but as request volume grows, reading from the database each time becomes a bottleneck, so a cache layer (commonly Redis) is added to accelerate reads.
Simple Full‑Load Cache Strategy
The most straightforward approach is to load all data into the cache without expiration, write only to the database, and use a scheduled task to refresh the cache.
Database data is fully flushed into the cache (no TTL).
Write requests update the database only.
A periodic job syncs the database to the cache.
Advantages: read requests hit the cache directly, yielding high performance. Drawbacks: low cache utilization (stale, rarely‑accessed data stays in cache) and data inconsistency because the cache is refreshed on a timer.
Improving Cache Utilization and Consistency
To maximize cache utilization, only hot data should be kept:
Write requests still update the database only.
Read requests first check the cache; on miss, they read from the database and rebuild the cache.
Cached entries are given an expiration time.
This ensures that infrequently accessed data expires, leaving only hot data in the cache.
Ensuring Consistency When Updating Data
When a record is modified, both the database and the cache must be updated. Two ordering options exist:
Update cache first, then the database.
Update the database first, then the cache.
Both orders suffer from a failure in the second step, leading to stale data in either the cache or the database.
Concurrency Problems
Concurrent updates can cause the cache and database to diverge regardless of the chosen order. Example scenarios show how interleaved operations result in different values stored in the cache and the database.
Delete‑Cache Approaches
Another class of solutions deletes the cache instead of updating it. Two orders are possible:
Delete the cache, then update the database.
Update the database, then delete the cache.
Both suffer from the same “second‑step‑failure” issue, so additional mechanisms are needed.
Asynchronous Retry via Message Queues
Placing the second step (cache update or deletion) into a message queue allows asynchronous retries until the operation succeeds, improving reliability without blocking the main thread.
Subscribing to Database Change Logs
Instead of writing to a queue, applications can listen to database binlogs (e.g., MySQL Binlog) using tools like Canal. When a change is detected, the corresponding cache entry is deleted, eliminating the need for a separate queue write.
Recommended Consistent Solution
Combine the “update database then delete cache” pattern with either a message‑queue‑based asynchronous retry or binlog subscription to guarantee that both steps eventually succeed.
Master‑Slave Delay and Delayed Double Delete
In read‑write split scenarios, replication lag can cause stale data to be written back into the cache. A delayed double‑delete strategy—deleting the cache once immediately and again after a short delay—helps mitigate this risk, though the optimal delay is hard to determine in high‑concurrency environments.
Can Strong Consistency Be Achieved?
True strong consistency across cache and database typically requires heavyweight protocols (2PC, Paxos, Raft) that sacrifice performance. In practice, eventual consistency with careful retry and delay strategies is the realistic goal.
Summary
Cache improves read performance but introduces consistency challenges.
Full‑load caching is simple but unsuitable for large‑scale, high‑consistency needs.
Updating both DB and cache fails under concurrency; deleting the cache is preferable.
Use asynchronous retries via message queues or binlog subscription to ensure both steps succeed.
Delay‑double‑delete can alleviate replication‑lag issues but requires careful timing.
Sanyou's Java Diary
Passionate about technology, though not great at solving problems; eager to share, never tire of learning!
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.