Databases 15 min read

Ensuring Data Consistency Between MySQL and Redis: Strategies and Best Practices

To keep MySQL and Redis synchronized, the article defines consistency, examines read‑only and read‑write cache inconsistency cases, and recommends practical strategies such as update‑DB‑then‑delete‑cache with message‑queue retries, binlog‑driven updates, delayed double‑delete, and Redis distributed locks, while outlining stronger protocols and key design considerations.

Tencent Cloud Developer
Tencent Cloud Developer
Tencent Cloud Developer
Ensuring Data Consistency Between MySQL and Redis: Strategies and Best Practices

Introduction – This article explains the concept of data consistency between MySQL and Redis, analyzes inconsistency scenarios in both single‑threaded and multi‑threaded environments, and proposes concrete consistency strategies.

1. What Is Data Consistency?

Data is considered consistent when the value stored in the cache equals the value stored in the database. Two cases are covered:

Cache contains data and its value equals the database value.

Cache is empty; the database holds the latest value, which will be written back to the cache on the next read.

Inconsistency occurs when the cache value differs from the database value, causing stale reads.

2. Inconsistency Scenarios and Countermeasures

Cache Types

Read‑only cache – Uses the "update DB + delete cache" strategy.

Read‑write cache – Uses the "update DB + update cache" strategy.

(1) Read‑only cache (update DB + delete cache)

Insert : write directly to the DB; the first read will miss the cache, fetch from DB and populate the cache – no inconsistency.

Update/Delete : order of operations (delete cache → update DB or update DB → delete cache) can cause temporary inconsistency.

Non‑concurrent case: ensure both steps succeed.

Concurrent case: avoid other threads reading stale data during the gap.

Suggested solutions :

Message queue + asynchronous retry: persist the second step (delete or update) to a queue; if it fails, retry until success.

Subscribe to MySQL binlog (e.g., Canal) and push changes to a queue for cache updates.

Set cache expiration + delayed double‑delete to achieve eventual consistency.

Code example for the delayed double‑delete approach:

redis.delKey(X);
 db.update(X);
 Thread.sleep(N);
 redis.delKey(X);

(2) Read‑write cache (update DB + update cache)

Two write‑back models:

Synchronous write‑through : update DB and cache within a transaction – provides strong consistency but may affect performance.

Asynchronous write‑back : write only to cache; later evict and persist to DB – risk of data loss if cache fails.

In high‑concurrency scenarios, additional measures are needed:

Distributed lock (e.g., Redis lock) to serialize updates.

Record cache reads and compare with delayed messages for compensation.

Use binlog subscription to delete stale keys.

Java example using Redis read/write locks:

public void write() {
    Lock writeLock = redis.getWriteLock(lockKey);
    writeLock.lock();
    try {
        redis.delete(key);
        db.update(record);
    } finally {
        writeLock.unlock();
    }
}

public void read() {
    if (caching) {
        return;
    }
    // no cache
    Lock readLock = redis.getReadLock(lockKey);
    readLock.lock();
    try {
        record = db.get();
    } finally {
        readLock.unlock();
    }
    redis.set(key, record);
}

3. Strong Consistency Strategies

For true strong consistency, protocols such as 2PC, 3PC, Paxos, or Raft are required, but they incur high latency. Practical alternatives include:

Temporarily store concurrent reads during DB update, then serve from DB after cache deletion.

Serialize all read/write requests via a single‑threaded queue.

Use Redis distributed read/write locks to guarantee mutual exclusion.

4. Additional Considerations

Key‑value size: keep each KV < 1 KB to fit within a single MTU packet.

Hot keys: replicate or shard hot read/write keys to avoid hotspot overload.

Prevent cache server crashes (cache penetration, avalanche, thundering herd) by using empty‑value caching, Bloom filters, rate limiting, etc.

5. Decision‑Making Process for Consistency Strategy

Identify cache type (read‑only vs read‑write).

Determine required consistency level (eventual vs strong).

Choose synchronous or asynchronous update method.

Select concrete workflow (e.g., DB → queue → delete cache, or DB → delete cache directly).

Fill in implementation details (locking, retry, expiration, etc.).

Recommendation : Prefer the "update DB then delete cache" sequence with a message‑queue‑based retry mechanism, optionally combined with binlog subscription for verification. This minimizes cache‑miss pressure on the DB and simplifies timing estimation compared to the opposite order.

Redisdata consistencyMySQLMessage Queuecache strategyDistributed Lock
Tencent Cloud Developer
Written by

Tencent Cloud Developer

Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.

0 followers
Reader feedback

How this landed with the community

login 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.