Mastering Cache Consistency: Strategies to Prevent Stale Data in High‑Concurrency Systems
This article examines why cache‑database consistency problems arise under high concurrency, compares common update orders, explains delayed double‑delete and cache‑aside patterns, and presents practical solutions such as retry mechanisms, message queues, and MySQL binlog subscription to keep data synchronized.
Introduction
Cache is a low‑cost way to boost system performance, but since its inception developers have struggled with cache‑database consistency, especially when fixing bugs introduces new issues.
Keywords
Atomicity, Transactionality, Data Consistency, Dual‑Write Consistency
Cache Query
Typical flow: query the cache first; if it misses, query the DB and rebuild the cache.
Cache Update
Questions arise: should the DB be updated before the cache, or vice‑versa? In normal cases either works, but high‑concurrency scenarios demand careful consideration.
1. Update DB then Update Cache
Thread A updates DB at 1 s, then cache at 10 s. Thread B updates DB at 3 s, then cache at 5 s. The different ordering can cause the cache to hold an older value while the DB holds a newer one, leading to stale data until the cache expires.
2. Update Cache then Update DB
Thread A updates cache at 1 s, then DB at 10 s; Thread B updates cache at 3 s, then DB at 5 s. Here the cache ends up with the newer value while the DB retains the older one.
Why These Issues Occur
Because updating the cache and the DB are two separate operations, their relative order cannot be guaranteed under concurrency.
3. Delete Cache then Update DB
Deleting the cache before updating the DB eliminates the race condition: both threads modify only the DB, and the cache is rebuilt on the next read.
4. Delayed Double Delete
Steps: (1) Delete cache, (2) Update DB, (3) Sleep for a short period, (4) Delete cache again. The sleep ensures that a concurrent read that repopulates the cache finishes before the first delete completes. The exact sleep duration is hard to determine, so this method is not foolproof.
5. Cache‑Aside (Update DB then Delete Cache)
This pattern, used by Facebook’s “Scaling Memcache at Facebook”, updates the DB first, then invalidates the cache. It works well for most cases, but a read that misses the cache while a write is in progress can still insert stale data.
Failure Scenarios
If the DB update succeeds but cache deletion fails, the cache holds an outdated value, causing inconsistency. The reverse also leads to problems.
Solutions
Retry Mechanism : Use a message queue to retry cache deletion until it succeeds, then remove the task from the queue.
Subscribe to MySQL Binlog : After a successful DB update, capture the change via binlog (e.g., using Alibaba’s Canal) and delete the cache asynchronously.
Practical Recommendations
Cache‑aside is not a universal cure; it reduces cache hit rate because caches are frequently invalidated.
To mitigate stale data, consider distributed locks before updating cache (at the cost of performance) or set short cache TTLs.
Conclusion
There is no silver bullet for cache consistency. Choose the strategy that best fits your workload, balancing consistency, performance, and cache hit rate.
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.
Alibaba Cloud Developer
Alibaba's official tech channel, featuring all of its technology innovations.
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.
