In backend architecture interviews, data consistency between Redis cache and databases serves as both a test of technical depth and a dividing line between junior developers and senior architects. Merely suggesting "setting TTL" is insufficient; TTL is a passive fallback that fails to address dirty data caused by network jitter, service restarts, or concurrency timing errors under high concurrency. Introducing cache essentially upgrades the system to a micro-distributed architecture. Per the CAP theorem, one must trade off between high performance and strong consistency, typically aiming for eventual consistency with a dirty data window compressed to milliseconds. A mature response must be grounded in the Cache Aside Pattern, understanding why "deleting cache" outperforms "updating cache" regarding idempotency and safety under high-concurrency Race Conditions, and why "updating the database before deleting the cache" is the industry standard. Additionally, to mitigate the risk of "cache deletion failure," one must master delayed double deletion, compensation retries via message queues, and asynchronous synchronization based on Canal subscribing to MySQL Binlog. This article analyzes the core difficulties and architectural trade-offs of dual-write consistency through seven common misconceptions and underlying concurrency principles, helping you build a systematic solution that handles massive concurrency while ensuring data accuracy.
Why is "Data Consistency" the Core Question in Cache Design?
In interviews, when the topic turns to Redis or cache architecture, "How to ensure data consistency between the cache and the database" is almost a mandatory question. This is not just examining your familiarity with the Redis API, but testing your deep understanding of distributed system design trade-offs.
The original intention of introducing caching is for High Performance. However, according to the CAP Theorem of distributed systems, given that Partition Tolerance is inevitable, we often have to make difficult choices between Availability and Consistency. When you store data dispersedly in two places—the database (MySQL) and the cache (Redis)—the system has actually become a miniature distributed architecture. At this point, any network jitter, service restart, or concurrent timing anomaly can lead to discrepancies between the "two copies of data."
Don't Just Use "Expiration Time" as a Shield
Many junior developers, when facing this question, habitually answer: "Set an expiration time (TTL), and the data will naturally reload after it expires."
This answer is often considered unsatisfactory in the eyes of interviewers because it sidesteps the core conflict:
- Passive defense rather than active control: TTL is a fallback mechanism, not a consistency guarantee strategy. During the window period before the data expires (which could be 5 minutes or even 1 hour), the business side may continue to read dirty data.
- Business scenarios do not tolerate it: For news lists, users seeing an old headline might be harmless; but for e-commerce inventory, financial account balances, or configuration switches, data inconsistency of even a few seconds can lead to overselling, financial risks, or logic errors.
Pursue "Eventual Consistency" Rather Than "Strong Consistency"
It needs to be clarified that in the vast majority of internet scenarios using Redis, pursuing Strong Consistency like that of bank transfers is impractical. Achieving strong consistency usually requires introducing distributed transactions (such as 2PC, 3PC) or complex consensus algorithms (such as Paxos/Raft), which will bring huge performance overheads, directly negating the original intention of introducing caching.
Therefore, the answer the interviewer is truly expecting is how you can minimize the time window of data inconsistency through architecture design, i.e., achieve Eventual Consistency. This requires developers to have a clear anticipation of “Race Conditions” in concurrent scenarios and be able to choose the most appropriate synchronization strategy based on the business's tolerance for dirty data.
In short, this question is not examining a "perfect solution," but rather whether you have the ability to find a balance point on the tightrope between high performance and data accuracy.
Basic Pattern: The Correct Approach to the Cache Aside Pattern

In the vast majority of non-hardware accelerated business development scenarios (such as user profiles, product inventory, and order status), the most commonly used caching strategy is known as the Cache Aside Pattern.
When an interviewer asks "How to ensure consistency," you must first clarify your baseline pattern. Many beginners tend to confuse strategies like Write Through or Write Behind, but in the standard Redis + MySQL architecture, Cache Aside is the absolute mainstream in the industry.
Standard Interaction Flow
The core logic of Cache Aside is: The Application interacts directly with the database and cache, rather than having the cache component proxy database operations.
- Read Flow:
- The application receives a read request and first checks the cache.
- Cache Hit: Directly return the cached data.
- Cache Miss: Read data from the database, write (Set) the data back to the cache, and then return.
- Write Flow:
- Update the data in the database.
- Delete (Invalidate) the corresponding data in the cache.
Key Decision: Why "Delete Cache" Instead of "Update Cache"?
This is the first major trap in interviews. Many candidates intuitively think: "After modifying the database, I should also update the old value in the cache to the new value, so that the next read will be faster."
Absolutely do not do this. In high-concurrency environments, the "Double Write Mode" (Update DB + Update Cache) is a hotbed for data dirty reads.
Scenario Analysis: The Concurrency Disaster of Double Write Mode
Assume there are two concurrent write requests. Thread A attempts to change the user age to 10, and Thread B attempts to change it to 20:
- Thread A updates the database (Age = 10).
- Thread B updates the database (Age = 20).
- Thread B updates the cache (Age = 20).
- Thread A updates the cache (Age = 10).
Result: The database is 20 (new value), but the cache is 10 (old value). Due to network jitter or CPU scheduling differences, the execution order of requests cannot be guaranteed, leading to an Overwrite error and creating persistent dirty data.
The Advantages of Deleting Cache (Lazy Loading)
In contrast, the Delete Cache strategy is more robust and efficient:
- Avoid Concurrency Contention: Deletion is an idempotent operation (to some extent) and does not involve the timing overwrite issue of new and old values. Once deleted, the next read request will automatically trigger the "Read DB + Write Back Cache" logic, utilizing the database's transaction features to ensure the latest value is read.
- Lazy Loading Saves Resources: If a piece of data is modified 100 times in 1 minute but only read once. Using the "Update Cache" strategy, you need to write to Redis 100 times; using the "Delete Cache" strategy, you only need to delete 100 times (or even fewer, as no action is needed if it is already deleted), and only that last read will generate one Redis write. This greatly reduces wasted calculation and I/O overhead.
Since we have determined that "write operations need to delete the cache," the next core point of controversy becomes: Should we delete the cache first, or write to the database first? The different order of these two operations leads to completely different concurrency risks.
The Focus of Controversy: Delete Cache First or Write to Database First?

In the Cache Aside pattern, the execution order of "updating the database" and "deleting the cache" directly determines the strength of data consistency in concurrent scenarios. This is not merely a question of coding order, but a test of the depth of understanding regarding concurrent Race Conditions.
In an interview, if you answer "both are fine" or "it depends on the mood," you will often be flagged as lacking practical experience in high concurrency. The industry-recognized standard answer is "update the database first, then delete the cache", but to get full marks, you must be able to clearly explain why the other scheme is wrong through scenario deduction, as well as the potential minor risks of the standard scheme.
1. Why is "Delete Cache First, Then Update Database" Wrong?
This scheme seems intuitive: clean up old cache first, then write new data. However, in read-write concurrent scenarios, it is extremely likely to cause serious dirty data retention issues.
Scenario Deduction (Race Condition):
Assume a record X = 10 in the database.
- Thread A (Write Request): Prepares to update
Xto20. It executes delete cache first. - Thread B (Read Request): Enters concurrently. Finds the cache empty (deleted by A), so it queries the database.
- Thread B: Reads the database. Since Thread A hasn't updated the DB yet, Thread B reads the old value
10. - Thread B: Writes the old value
10back to the cache. - Thread A: Completes the database update,
Xbecomes20.
Consequence:
At this point, the database has the new value 20, but the cache permanently holds the old value 10 (until the expiration time is reached). This inconsistency is inevitable; as long as a read request executes in the "gap" of the write request, dirty data will be generated. As analyzed by the Tencent Cloud Technical Community, this scheme causes the cache to hold dirty data for a long time, so it should be avoided in production environments.
2. Why is "Update Database First, Then Delete Cache" the Mainstream Choice?
This order is the standard implementation of the Cache Aside Pattern and is also adopted by major companies like Facebook. Although it cannot guarantee 100% strong consistency, in the vast majority of business scenarios, it minimizes the probability of inconsistency.
Scenario Deduction (Why it is safer):
Assume database X = 10.
- Thread A (Write Request): Updates the database first,
Xbecomes20. - Thread B (Read Request): Reads concurrently.
- Case 1 (Cache Hit): Reads the old cache
10. This is possible before Thread A deletes the cache, but this is only a brief "eventual inconsistency"; once A deletes the cache, subsequent requests will be able to read the new value. - Case 2 (Cache Miss): Thread B reads
20from the database and writes it back to the cache. Data is consistent.
- Case 1 (Cache Hit): Reads the old cache
- Thread A: Executes delete cache.
The Only Theoretical Risk (Extremely Low Probability):
To cause dirty data with this scheme, an extremely harsh concurrent condition must be met:
- The cache just happens to expire (or does not exist).
- Thread B reads the database and gets the old value
10(at this time Thread A hasn't started writing yet). - Thread A updates the database to
20. - Thread A deletes the cache.
- Thread B writes the old value
10into the cache (Note: This requires Thread B's "Read DB + Write Cache" operation to take longer than Thread A's "Write DB + Delete Cache", AND step 5 must happen after step 4).
In actual engineering, database write operations (involving locking, log persistence) are usually much slower than in-memory cache write operations. Therefore, the probability of Thread B writing back the old value only after Thread A completes the entire update process is extremely low. According to the analysis by Xiaolin Coding, this extreme situation belongs to "theoretical possibility" and rarely appears in actual high-concurrency systems.
3. The Real Risk Point
Although "update DB first, then delete cache" avoids most logical loopholes, it introduces a realistic engineering challenge: What if the second step "delete cache" fails?
If the database update succeeds, but the Redis delete command fails due to network jitter or timeout, the cache will still retain the old data and will not be corrected. This is the real testing point when the interviewer asks about "data inconsistency," and it is also the opportunity to introduce "delayed double deletion" or "message queue retry mechanisms."
Advanced Strategies: How to Resolve "Deletion Failure" and "Concurrent Dirty Reads"?
In the previous section, we established the Cache Aside Pattern (update database first, then delete cache) as the standard solution for most business scenarios. For 99% of non-core businesses (such as user avatars, news lists, etc.), this strategy, combined with a reasonable Time To Live (TTL), is sufficient. Even if brief data inconsistency occurs, relying on TTL's automatic expiration can achieve eventual consistency, offering an extremely high cost-performance ratio.
However, interviewers' follow-up questions usually target the remaining 1% of extreme scenarios, or core links with extremely high requirements for data consistency (such as flash sale inventory, financial accounts). In these high-concurrency or unstable network environments, the standard solution exposes two fatal risks:
- Deletion Failure: If the database update succeeds, but the subsequent Redis deletion operation fails due to network jitter or service downtime, dirty data will remain in the cache permanently (until it expires).
- Concurrent Dirty Reads: In a database read-write separation architecture, there is latency in master-slave synchronization. If Thread A updates the master database and deletes the cache, while Thread B reads old data from the slave database before synchronization completes and writes it back to the cache, the cache reverts to dirty data.
This chapter will delve into two advanced solutions to address these vulnerabilities: one is the "Delayed Double Deletion" strategy common in interviews, and the other is the "Binlog-based Asynchronous Deletion" architecture more highly regarded in the industry. We will analyze how they respectively sacrifice a certain amount of throughput or increase architectural complexity in exchange for higher consistency guarantees.
Strategy 1: Delayed Double Delete Strategy

In interviews, when asked about the concurrent dirty read issues caused by "deleting cache first vs. updating DB first," "Delayed Double Delete" is often the first advanced answer candidates think of. It adds a "follow-up" step to the standard Cache Aside pattern, attempting to smooth out inconsistencies caused by concurrency through a time difference.
Core Process and Design Intent
The core of Delayed Double Delete lies in the "double deletion": executing a cache deletion operation both before and after updating the database. Its standard execution steps are as follows:
- Delete Cache: Clear old data first to prevent read requests from directly hitting stale cache.
- Update Database: Execute business logic and commit the transaction.
- Sleep (Sleep T): Suspend the thread or delay asynchronously for a period of time.
- Delete Cache Again: Clean up dirty data that might have been written to the cache by concurrent read requests during steps 2 and 3.
Why "Sleep"?
This strategy mainly aims to solve a specific race condition: while Thread A is updating the database, Thread B discovers a cache miss, reads the database (potentially reading the old value at this moment), and writes the old value into the cache. Without the second deletion, this "dirty old value" would remain for a long time. The sleep time T is essentially designed to cover "database master-slave replication lag" + "execution time of concurrent read requests", ensuring that by the time of the second deletion, all dirty data write actions by concurrent threads have been completed.
In-Depth Analysis: The "High-Score Trap" in Interviews
Although Delayed Double Delete seems logically sound, it is often a solution that "looks good on paper" when implemented in a production environment. In an interview, if you can proactively point out the following pain points, it demonstrates more engineering experience than simply reciting the process.
1. The Invisible Killer of Throughput
The most intuitive problem lies in Thread.sleep(T). If sleep is executed in the main thread of core business logic, even for just a few dozen milliseconds, it will cause the interface response time (RT) to skyrocket, severely dragging down system throughput.
Optimization Idea: It is usually recommended to make the "second deletion" asynchronous. For example, use an additional thread pool or a simple delay queue to execute the final deletion step, avoiding blocking the main business flow.
2. The Hard-to-Quantify "Magic Time T"
The setting of parameter T is an imprecise science. As pointed out by the Huawei Cloud Technology Blog, this time needs to be greater than "maximum master-slave replication lag + read request execution time + network jitter buffer".
- Time too short: Cannot cover master-slave lag or slow queries; dirty data will still be written to the cache, rendering the strategy ineffective.
- Time too long: Although safety increases, if it is synchronous sleep, the performance cost is too high; if it is asynchronous deletion, it means the window of data inconsistency is prolonged.
In actual production, database master-slave lag fluctuates dynamically (e.g., encountering large transactions or network jitter), so a statically configuredTis difficult to cope with all extreme situations.
3. The Risk of Second Deletion Failure
If step 4 fails (e.g., Redis network jitter), dirty data will still remain in the cache. To ensure eventual consistency, you often need to introduce a retry mechanism. Once retries are introduced, the complexity of the logic rises rapidly—you might need to throw the deletion action into a message queue to guarantee "at least once consumption".
Interviewer's Perspective: When to Use?
Delayed Double Delete is not without merit; it is a low-cost compromise solution.
- Applicable Scenarios: Read-heavy/write-light, medium concurrency, and businesses with high tolerance for consistency (can accept second-level dirty reads), such as user profile updates or non-core configuration items.
- Unsuitable Scenarios: Flash sale inventory deduction, financial account balance changes, and other scenarios requiring extremely high consistency or involving high-frequency writes.
When you propose this solution in an interview, be sure to add: "This is a trade-off strategy before introducing complex middleware (such as Canal + MQ). It solves 99% of concurrent dirty reads with minimal code changes, but it cannot provide a 100% consistency guarantee."
Scheme 2: Binlog-based Asynchronous Deletion (Canal + MQ)

If the interviewer follows up with: "What if the business code cannot tolerate any blocking caused by Thread.sleep, or if we need to completely decouple the cache maintenance logic from the business logic?" At this point, you need to bring out the industrial-grade heavy weapon: the Binlog-based asynchronous deletion pattern.
This is an architectural solution based on Eventual Consistency, which physically separates "data updates" from "cache eviction." It is currently the mainstream choice for major tech companies when handling high concurrency and core links (such as orders and accounting).
1. Core Architecture Process
In this scheme, the business code is only responsible for "updating the database" and does not need to write any code to manipulate Redis. The entire process is automatically driven by the infrastructure:
- Application Layer Update: The business service (App) executes SQL to update the MySQL database, and the process ends immediately upon transaction commit.
- Log Recording: MySQL automatically writes changes to the Binlog.
- Log Capture: Middleware (such as Alibaba's open-source Canal) masquerades as a MySQL Slave to subscribe to and parse the Binlog in real-time.
- Message Delivery: Canal delivers the parsed change data (Table, Key, Value) to a message queue (MQ, such as Kafka or RocketMQ).
- Asynchronous Consumption: A dedicated consumer service (Consumer) listens to the MQ, parses the message, and executes
Redis.del(key).
2. Why is this the "Perfect Answer" in Interviews?
Compared to "Delayed Double Deletion," this scheme solves three pain points at the architectural level:
- Complete Decoupling:
Business code does not need to care whether the cache exists, nor does it need to introduce Redis client dependencies. If the cache strategy changes in the future (e.g., switching from Redis to another storage, or changing Key rules), only the downstream Consumer code needs to be modified, with zero awareness required from the upstream business. - Traffic Peak Shaving and Lossless Performance:
Since Redis IO and Sleep waiting are removed from business threads, the interface response time (RT) depends only on the database write operation, allowing write performance to reach its physical limit. - Reliability Backstop:
This is the biggest "killer feature" of this scheme. If Redis goes down or network jitter causes deletion failure, utilizing the MQ's ACK mechanism (Acknowledgment), the consumer can refuse to acknowledge the message. The MQ will automatically retry until the deletion is successful. This fundamentally solves the problem of "dirty data retention caused by deletion failure."
3. "Deep Water" Details of Implementation
In an interview, simply drawing a flowchart is not enough; you also need to demonstrate control over implementation details to prove that you possess practical engineering experience:
- Binlog Format Requirements:
You must set MySQL'sbinlog_formatto ROW mode. Only ROW mode can record the change details of every row, avoiding inconsistencies produced by STATEMENT mode under certain specific SQLs (such as thenow()function). - Idempotency of Message Consumption:
MQ might deliver messages repeatedly, or Binlog might generate duplicate events. The deletion operation (del) on the Consumer side is naturally idempotent, but if complex cache reconstruction logic is involved, extra attention must be paid to preventing duplication. - Cleaning Multi-level Caches:
If the architecture also includes local caches (such as Caffeine), you can notify all application nodes to clean their local caches via the MQ Broadcast mode. This is another extended advantage of the Binlog scheme compared to simple double deletion.
4. Architectural Trade-offs: The Cost of Introducing Complexity
No solution is perfect. When recommending this scheme, you must conclude with this to demonstrate your architectural vision:
"Although the Binlog-based scheme performs excellently in terms of consistency and performance, it introduces infrastructure complexity. We need to maintain the Canal cluster, MQ cluster, and dedicated consumer services. For small to medium-sized teams or non-core businesses, this might be 'over-engineering.' Therefore, the prerequisite for choosing this scheme is: the business has high concurrency write demands, and the team possesses comprehensive middleware operations and maintenance capabilities."
Through this "praise first, caution later" approach, you not only solve the technical problem but also reflect your sensitivity to technical costs (ROI), which is a core quality of a senior engineer.
The Ultimate Resort: Distributed Locks and Strong Consistency
In the vast majority of interview scenarios, the "cache consistency" we discuss usually refers to Eventual Consistency. The interviewer might ask a follow-up question: "What if my business requires Strong Consistency and absolutely cannot tolerate reading dirty data, such as in financial transactions or extremely sensitive inventory deductions?"
At this point, you need to bring out the "ultimate resort": Sacrifice some concurrency performance and introduce distributed locks.
When Must Strong Consistency Be Used?
When the business scenario demands data accuracy over concurrency performance, ordinary "delayed double deletion" or "asynchronous messaging" schemes are no longer sufficient. Typical scenarios include:
- Financial Account Balances: After a user tops up or transfers money, the balance query must immediately display the latest amount without even milliseconds of delay.
- E-commerce Flash Sale Inventory: Although flash sales usually deduct inventory in Redis, in certain strict inventory synchronization scenarios, absolute consistency between the database and cache must be guaranteed to prevent overselling.
- Configuration Center Metadata: After certain global system configurations are modified, all nodes must take effect immediately, and no residual old configurations can be tolerated.
Solution: Read-Write Lock
To achieve strong consistency between cache and database, the most direct method is to "serialize" parallel operations. However, if a Mutex is applied to all requests, the system throughput will plummet. Therefore, a more mature solution is to use distributed read-write locks.
In the Java ecosystem, the most commonly used implementation is Redisson's RReadWriteLock. Its core logic is as follows:
- Read Data (Read Lock):
- When multiple threads read data simultaneously, they apply for a read lock.
- Read locks are shared, meaning that if there are no current write operations, thousands of read requests can execute concurrently without blocking.
- If a write lock exists at this time, read requests will be blocked until the write lock is released.
- Write Data (Write Lock):
- When the database needs to be updated, the thread applies for a write lock.
- Write locks are exclusive. Once a write lock is applied, other read and write requests will be blocked until the current thread completes all "update database + update/delete cache" operations.
Through this mechanism, we force "read" and "write" operations to be mutually exclusive, thereby completely eliminating the concurrency time windows that exist in "update then delete" or "delete then update" strategies.
Reference: For specific implementation details and consistency guarantees, you can refer to the relevant practices in Implementing Redis Cache Distributed Locks and Data Consistency with Redisson and SpringCache.
The Fatal Cost: Collapse of Concurrency Performance
Although distributed locks solve the problem of data inconsistency, they violate the original intention of introducing caching—high performance.
- Performance Bottleneck: Once a write lock is applied, all read requests are blocked. In high concurrency scenarios (e.g., hot Key updates), this causes the request queue to instantly backlog, and response time (RT) skyrockets from a few milliseconds to hundreds of milliseconds or even timeouts.
- System Complexity: Introducing distributed locks increases system fragility. You need to handle lock timeout mechanisms (Watch Dog), deadlock detection, and lock safety during Redis cluster failures (such as the Redlock Algorithm solving the problem of lock loss during master-slave failover).
The "Red Line" in the Interviewer's Eyes
When answering this question, your attitude must be cautious and firm. Do not easily suggest using distributed locks unless you explicitly point out their costs.
You can summarize it like this:
"Using read-write locks can guarantee 100% strong consistency, but this comes at the cost of sacrificing concurrency capabilities. If the business truly requires strong consistency, we should first reflect: Does this data really need caching? Is it more appropriate to query the database directly? Only in extreme scenarios with 'many reads, few writes' and rigid consistency requirements should we consider using distributed read-write locks."
This not only demonstrates your mastery of technology but also reflects the trade-off thinking in architecture design.
Decision Checklist: How to Choose for Different Business Scenarios?

In interviews, when asked "which solution should be chosen," the biggest taboo is directly throwing out a "best practice." There are no silver bullets in architecture design, only Trade-offs. To demonstrate your technical depth, it is recommended to provide a decision path based on specific business scenarios from three dimensions: Consistency Level, Implementation Complexity, and Performance Impact.
Core Strategy Comparison Overview
Here is a detailed comparison of four mainstream strategies, which you can use as a "mind map" during interviews:
Strategy Scheme | Consistency Level | Implementation Complexity | Performance Impact | Applicable Scenarios |
|---|---|---|---|---|
Cache Aside (Update DB then Delete Cache) | Eventual Consistency (Weak) | ⭐ (Low) <br> Only code logic adjustments needed | 🟢 (Excellent) <br> Only adds one Redis deletion overhead | 90% of General Business. Scenarios like articles/news, basic user info where short-term inconsistency is highly tolerable. |
Delayed Double Delete | Eventual Consistency (Medium) | ⭐⭐ (Medium) <br> Need to maintain delay time and thread management | 🟡 (Medium) <br> | Bursty High-Concurrency Writes. A transitional solution where heavy middleware cannot be introduced, but the probability of dirty data must be reduced. |
Async Binlog (Subscribe to Binlog for Async Deletion) | Eventual Consistency (Strong Guarantee) | ⭐⭐⭐ (High) <br> Relies on middleware like Canal/MQ | 🟢 (Excellent) <br> Business code fully decoupled, async processing doesn't block main flow | Core High-Concurrency Business. E.g., E-commerce flash sales, hot configurations, requiring data to be eventually consistent without affecting write performance. |
Distributed Lock / Strong Consistency Read-Write Lock | Strong Consistency (Strong) | ⭐⭐⭐ (High) <br> Need to handle deadlocks, lock timeouts, and degradation | 🔴 (Poor) <br> Request serialization, throughput drops significantly | Funds/Strict Inventory. Special scenarios with zero tolerance for data errors and controllable concurrency volume. |
Selection Decision Funnel
In actual implementation or when answering interview questions, you can follow these "three-step" decision Heuristics:
1. Default Choice: Cache Aside Pattern
Mnemonic: "Use standard for read-heavy/write-light, tolerate second-level inconsistency."
For most internet applications (such as news lists, product detail pages), updating the database first, then deleting the cache is the most cost-effective choice. Although theoretically there is a tiny window where "a read operation reads old data before the write operation deletes the cache," in actual network environments, this probability is extremely low. As mentioned in some technical blogs, if the team size is small and there is no dedicated DBA or MQ infrastructure, this is the safest solution.
2. Advanced Scenario: Introduce Async Compensation (Async Binlog)
Mnemonic: "High concurrency writes fear dirty reads, decouple and retry to ensure eventual consistency."
When the business faces high concurrency writes or high data sensitivity (long-term dirty data is not allowed), simple Cache Aside may lead to long-term data inconsistency due to deletion failures. At this time, using Canal to listen to Binlog and deliver to a Message Queue is the best practice.
- Advantage: Even if Redis goes down or network jitters occur, the message queue's retry mechanism ensures the cache is eventually deleted (At-least-once).
- Applicability: Mid-to-large projects with established middleware infrastructure.
3. Extreme Scenario: Abandon Cache or Use Locks
Mnemonic: "Don't push your luck with money, either use strong locks or check the DB."
If the business scenario involves user balances, transfers, or real-time inventory deduction, and the business side requires that "old data must absolutely not be seen":
- Option A (Recommended): Directly abandon the cache, all reads and writes go directly to the database (utilizing the database's MVCC and row locks to ensure consistency).
- Option B (Compromise): If cache must be used to withstand read pressure, then Distributed Read-Write Locks (ReadWriteLock) must be used. Although this sacrifices concurrency performance, it enforces consistency through serialization.
Summary of High-Scoring Interview Scripts
"In my experience, discussing consistency without the business context is nonsense.
For the vast majority of read-heavy, write-light scenarios, I would directly adopt Cache Aside (Update DB then Delete Cache), combined with setting a reasonable expiration time as a safety net, because it is simple and efficient.
If it is a core link with high consistency requirements, such as a product center with tens of millions of traffic, I would introduce Binlog + MQ Async Deletion, utilizing the message queue's retry mechanism to eliminate the risk of 'deletion failure' and achieve highly reliable eventual consistency.
Only in zero-tolerance scenarios involving fund accounting would I consider using distributed locks, or simply remove the cache and query the database directly. After all, in such scenarios, data accuracy is far more important than response speed."







