This is the 7th day of my participation in the November Gwen Challenge. Check out the details: The last Gwen Challenge 2021

There are two types of cache inconsistencies:

  • Redis cache is old;
  • Values in the database are old values;

Cache consistency Requires that when there is a value in the cache, the value in the database must be consistent with the value in the cache.

Caches can be divided into read/write caches and read-only caches depending on whether write requests are received or not. The two cases of cache inconsistencies are different and need to be handled separately.

In read-only caches, new data is written directly to the database without caching, so cache inconsistencies do not occur. When deleting or modifying data, you need to delete the data in the database and cache. When deleting or modifying data in the database and cache, the old value will be generated when a fault occurs in any sequence, that is, the cache is inconsistent.

Different situation A potential problem
Delete the cache value before updating the database value The database update fails. As a result, the cache is missing when the database is accessed again, and the old value is read from the database when the database is read again
Update the database value first, then delete the cache value The cache deletion fails. As a result, a cache hit is found and the old value is read from the cache

How to resolve data inconsistency

Retry mechanism

Cached values to be deleted or database values to be updated can be temporarily stored in message queues. When the application fails to delete the cache or update the database values, the values can be re-read from the message queue and then deleted or updated again.

If the deletion or update is successful, these values need to be removed from the message queue to avoid duplication. If there is no success after a certain number of retries, you need to send an error message to the business layer.

However, the retry mechanism can still be problematic with large amounts of concurrency. Delete the cache first or update the database first.

Case 1: Delete the cache first and update the database later.

In the concurrent case, it is assumed that thread A deletes the cache first and updates the database later. In the meantime, thread B reads the data, finds that the cache is missing, and goes to the database to read the data, which will cause two problems:

  • Old data read by thread B;
  • Thread B finds that the cache is missing after reading the old data, so it will update the cache to the old value. In this way, the later reading thread will access the old value, resulting in data inconsistency.

In this case, thread A can use A delayed double deletion policy, that is, after updating the database, thread A will sleep for A while and then delete the cache. The purpose of this is to update the cache with the old value when thread B finds that the cache is missing, and then delete the old value from the cache.

Personally, I don’t think this strategy is very good. First of all, the delay time is hard to determine, so it is impossible to know when the next reader thread will update the cache. Secondly, in the case of large concurrency, when thread A has not done the delayed double deletion, a large number of threads will read the old values in the cache. So I think this solution will only reduce the probability of cache inconsistencies, not “silver bullet”.

Case 2: Update the database value and then delete the cached value.

In the case of concurrency, thread A is assumed to update the database before deleting the cached values. The thread will also read the old value in the cache before deleting it after updating the database. However, since the cache deletion operation is an in-memory operation, you can assume that this step is fast and not of great impact.

However, for normal business, such a short period of data inconsistency is not a big deal. If data consistency is required, either no caching is used or requests are serialized using distributed locks. The specific approach scored the scene selected.