Do you want to update the database or the cache first?

Time:2021-7-30

Hello, I’m glacier~~

Recently, my friends have been asking me whether to write the database first or write the cache first when writing data to the database after the cache is introduced into the system? What is the difference between writing the database first and writing the cache first? Today, let’s talk about this topic.

In essence, whether you write the database or write the cache first, it is to ensure the consistency of the data between the database and the cache, that is, the data consistency we often say.

With the rapid development of the Internet, today’s era has entered the DT era from the IT era. The Internet system architecture has also changed from the original single architecture to distributed and micro service architecture. In terms of data volume, the amount of data stored in each system is larger and larger, and the query performance of data is lower and lower. At this time, we need to constantly optimize. A common optimization method is to introduce cache. After the cache is introduced, when we insert data into the database, do we update the database first or update the cache first?

General use of cache

Cache, in essence, is an intermediate cache layer introduced to better coordinate two components with large speed differences. For example, if you need to read data into the CPU for calculation and processing, because the CPU’s operation speed is very fast, and the IO processing of the disk is many orders of magnitude slower than that of the CPU, each time you read data from the disk, the CPU will wait for disk IO for a long time and frequently. At this point, we can alleviate the speed difference between CPU and disk through memory.

Do you want to update the database or the cache first?

In terms of the use of cache, it is generally used according to the following process.

Do you want to update the database or the cache first?
We can also express it as the following sequence diagram.

Do you want to update the database or the cache first?

In the above usage example, we simply put the data into the cache and set an expiration time for the cache at most. After the expiration, the cache will be cleared naturally. Subsequent requests will get the data from the database and write the data to the cache because they can’t get the data in the cache.

However, in the subsequent operation of updating data, do you update the database, then update the cache or delete the cache? Or delete the cache first and then update the database?

Cache update policy

In theory, setting the expiration time for the cache is actually a manifestation of the final consistency in a. In this scheme, the expiration time can be set for the data stored in the cache. All write operations shall be subject to the database, and only the best efforts can be made for the cache operation. That is, if the database is successfully written and the cache update fails, as long as the expiration time is reached, the subsequent read requests will naturally read new values from the database and then backfill the cache. This is also the most commonly used method in general.

Update the database before updating the cache

In fact, many experienced partners are very opposed to this scheme. Why, let’s analyze it.

First of all, this scheme will have thread safety problems.

For example, if thread a and thread B update data at the same time, the following execution sequence may occur.

(1) Thread a updated the database
(2) Thread B updated the database
(3) Thread B updated the cache
(4) Thread a updated the cache

At this time, the data in the database is inconsistent with the cached data. This is because thread a updates the database first. Thread B updates the database and then updates the cache, possibly due to abnormal conditions such as the network. Thread a updates the cache only after thread B updates the cache, which leads to the inconsistency between the database data and the cached data.

Secondly, this scheme also has its inapplicable business scenarios.

First, a business scenario is a scenario where the database writes more and reads less. In this scenario, the strategy of updating the database first and then updating the cache will lead to frequent updates if the cache is not read, which will greatly waste the performance of the server.

Another business scenario is that the data in the database is not directly written to the cache, but requires a large number of complex operations to write the operation results to the cache. If the strategy of updating the database first and then updating the cache is used in this scenario, it will also cause a waste of server resources.

Delete the cache before updating the database

The scheme of deleting the cache first and then updating the database also has thread safety problems. For example, thread a updates the cache and thread B reads the cached data. The following execution sequence may occur.

(1) Thread a delete cache
(2) Thread B queries the cache and finds that there is no desired data in the cache
(3) Thread B queries the old data in the database
(4) Thread B writes the queried old data to the cache
(5) Thread a writes new data to the database

At this point, the data in the database is inconsistent with the data in the cache. If the cache deletion fails, the database data and cache data will be inconsistent.

Update the database before deleting the cache

Firstly, this method also has a very small probability of inconsistency between database data and cache data. For example, thread a performs query operation and thread B performs update operation. The order of execution is as follows.

(1) The cache just expired
(2) Request a to query the database and get the old value in the database
(3) Request B to write the new value to the database
(4) Request B to delete cache
(5) Request a to write the found old value to the cache

If the above sequence occurs, it will cause inconsistency between the data in the database and the data in the cache.

However, for the strategy of updating the database first and then deleting the cache, the probability of inconsistency between the database and the cache data is very low. The reason is that: (3) the write database operation takes less time than the read database operation in step (2), so it is possible to execute step (4) before step (5). However, often the read operation of the database is much faster than the write operation, so step (3) takes less time than step (2), which is difficult to appear.

If the cache deletion fails, the database data and cache data will be inconsistent.

In this way, it seems that none of the three schemes is safe. What should we do? The final is to introduce the retry mechanism.

Recommended use

In the actual production environment, it is recommended thatUse to update the database before deleting the cacheOperation of. So, how can we solve the problem under this strategy?

There are two schemes. One is to handle the failed retry operation in the program logic; In addition, with the help of Alibaba’s open source canal.

Manual retry failed

Do you want to update the database or the cache first?

The process is as follows
(1) Update database data;
(2) Failed to delete cached data
(3) Send the key to be deleted to the message queue
(4) Consume the message yourself and get the key to be deleted
(5) Continue to retry the delete operation until it succeeds

This scheme has a disadvantage of causing a large number of intrusions into the line of business code.

Synchronize database data

Let’s start with a diagram, which solves the inconsistency between database data and cache data from the overall architecture.

Do you want to update the database or the cache first?

The process is shown in the figure below:
(1) Update database data
(2) The database writes the change information of the data table data into the binlog log
(3) The subscriber obtains the required data and key
(4) The program logic handles the specific business logic, receives the subscription binlog and initiates the request to delete the cache.
(5) An attempt was made to delete the cache and the deletion failed
(6) Send this information to the message queue
(7) Retrieve the data from the message queue and retry the operation.

Well, that’s all for today. I’m glacier. I’ll see you next time~~