How to Keep Redis Cache Consistent with Database: Strategies and Pitfalls

This article examines the consistency challenges when using Redis as a cache for database data, compares three update strategies, and presents practical solutions such as delayed double‑delete, retry mechanisms, and handling cache penetration, avalanche, and thread‑safety issues in Java.

Programmer DD
Programmer DD
Programmer DD
How to Keep Redis Cache Consistent with Database: Strategies and Pitfalls

Cache Consistency Problem

When using Redis as a high‑performance cache, updating data can lead to inconsistency between the cache and the underlying database.

Three Update Strategies

Update database then update cache.

Delete cache then update database.

Update database then delete cache.

Analysis shows the first strategy can cause dirty data due to race conditions, while the second can produce stale reads if the cache is deleted before the database write completes. The third strategy, also known as the Cache‑Aside pattern, is widely adopted but still has edge cases.

Delay Double‑Delete Solution

To mitigate the second strategy’s inconsistency, a delayed double‑delete is used: delete the key, write to the database, sleep for a short period (e.g., 1 s), then delete the key again.

public void write(String key, Object data) {
    redis.delKey(key);
    db.updateData(data);
    Thread.sleep(1000);
    redis.delKey(key);
}

The sleep duration should be based on the expected read‑operation latency plus a safety margin.

Handling Cache‑Delete Failures

If the second delete fails, a retry mechanism is required. Two approaches are presented: (1) send the failed key to a message queue and retry until success; (2) subscribe to the MySQL binlog (e.g., using Canal) and perform asynchronous retries.

Other Cache Issues

Cache penetration – use placeholder values or Bloom filters.

Cache avalanche – stagger expiration times and use distributed locks.

Cache “no‑bottom‑hole” – avoid excessive mget calls by balancing node count.

HashMap Internals and Thread Safety

Since JDK 1.8, HashMap switches from linked‑list buckets to red‑black trees when a bucket exceeds eight entries, improving lookup performance. The structure is not thread‑safe; concurrent puts can lose entries or cause loops during resizing. Using synchronized wrappers or ConcurrentHashMap resolves these issues.

Common Java Thread Pools

newCachedThreadPool – unbounded thread creation with idle‑thread timeout.

newFixedThreadPool – fixed number of worker threads.

newSingleThreadExecutor – single worker guaranteeing task order.

newScheduledThreadPool – supports delayed and periodic tasks.

Understanding their parameters and limits (e.g., Integer.MAX_VALUE for cached pool) helps avoid resource exhaustion.

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.

JavadatabaseconcurrencyRedisCache Consistency
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

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.