Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the inconsistency between Redis and MySQL caches

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly explains "how to solve the write inconsistency between Redis and MySQL cache". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to solve the write inconsistency between Redis and MySQL caches.

Redis and mysql double write caches are inconsistent:

Text

Set the expiration time for cached data

Let's make it clear that, in theory, setting an expiration time for the cache is the solution to ensure ultimate consistency. Under this scheme, we can set the expiration time for the data stored in the cache. All write operations are based on the database, and we just try our best to cache the data. That is, if the database is successfully written and the cache update fails, as long as the expiration time is reached, the subsequent read request will naturally read the new value from the database and backfill the cache. Therefore, the idea discussed next does not depend on the scheme of setting an expiration time for the cache.

Here, let's first discuss three update strategies:

Update the database before updating the cache

Delete the cache before updating the database

Update the database before deleting the cache

Update the database before updating the cache

This plan is generally opposed by everyone. Why? There are two points as follows:

Reason 1 (thread safety perspective)

(1) Thread A updates the database

(2) Thread B updates the database

(3) Thread B updates the cache

(4) Thread A updates the cache

This shows that the request A to update the cache should be earlier than the request B to update the cache, but due to network and other reasons, B updated the cache earlier than A. This leads to dirty data, so it is not considered.

Reason 2 (business scenario perspective)

(1) if you are a business requirement with more write database scenarios and fewer read data scenarios, the cache will be updated frequently before the data is read, resulting in a waste of performance.

(2) if you write the value to the database, it is not written directly to the cache, but is written to the cache after a series of complex calculations. Then, after each write to the database, the write cache value is calculated again, which is undoubtedly a waste of performance. Obviously, it is more appropriate to delete the cache.

Delete the cache before updating the database

The reason for the inconsistency is that. At the same time, one request A for update operation, and the other request B for query operation. Then the following situations will occur:

(1) request A to write and delete the cache

(2) request B query found that cache does not exist.

(3) request B to query the database to get the old value.

(4) request B to write the old value to the cache

(5) request A to write the new value to the database

This will lead to inconsistencies. Moreover, if you do not set the expiration policy for the cache, the data will always be dirty.

So, how to solve it? Using delayed double deletion strategy

Cache delayed double deletion public class CacheServiceImpl implements ICacheService {@ Resource private RedisOperator redisOperator; @ Autowired private IShopService shopService; / / 1. Using delayed double deletion to solve database and cache consistency @ Override public void updateHotCount (String id) {try {/ / delete cache redisOperator.del ("redis_key_" + id); / / update database shopService.updataHotShop (); Thread.sleep (1000) / / dormant for 1 second / / delay deletion of redisOperator.del ("redis_key_" + id);} catch (InterruptedException e) {e.printStackTrace ();}} @ Override public Integer getHotCount (String id) {return null;}}

Explanation:

Eliminate cache first

Write the database again

Hibernate for 1 second and then eliminate the cache (by doing so, the cache dirty data caused by 1 second can be deleted again. )

In response to the above situation, readers should evaluate the time-consuming business logic of reading data for their own projects. Then the dormancy time of writing data can be increased by several hundred ms on the basis of reading data business logic. The purpose of this is to ensure that the read request ends, and the write request removes the cache dirty data caused by the read request.

What if the database uses a read-write separation architecture? (the master library is responsible for the write operation and the slave library is responsible for the read operation)

Ok, in this case, the reasons for the data inconsistency are as follows: two requests, one for A for update operation and the other for B for query operation.

(1) request A to write, delete the cache, request A to write data to the master database, and haven't started synchronizing the slave database.

(2) (within 1s) request B query cache, no cache found, request B to query the slave database, the master-slave synchronization has not been completed, the old value is found, and the old value is written to the cache.

(3) the master library completes the master-slave synchronization and changes from the library to the new value.

The above process is the problem of data inconsistency, and the double deletion delay strategy is also used. However, the sleep time is modified to add hundreds of ms to the delay time of master-slave synchronization.

With this synchronous elimination strategy, what if the throughput is reduced?

Ok, then delete the second time as asynchronous. Start your own thread and delete it asynchronously. In this way, the written request does not have to sleep for a while and then return. By doing so, increase the throughput.

The second deletion, what if the deletion fails?

This is a very good question, because if the second deletion fails, the following situation occurs. There are still two requests, one for A for update operation and the other for B for query operation. For convenience, it is assumed to be a single database:

(1) request A to write and delete the cache

(2) request B query found that cache does not exist.

(3) request B to query the database to get the old value.

(4) request B to write the old value to the cache

(5) request A to write the new value to the database

(6) request An attempted to delete request B to write to the cache value, but failed.

Ok, that means. If you fail to delete the cache the second time, the cache and database inconsistencies will occur again.

How to solve the problem?

For the specific solution, let's look at the blogger's analysis of the strategy of updating the database first, and then deleting the cache update strategy.

Delete cache retry mechanism

Whether it is delayed double deletion or Cache-Aside 's operation of the database before deleting the cache, there may be a failure to delete the cache in the second step, resulting in data inconsistency. You can use this scheme to optimize: delete a few more times if you fail to delete, to ensure the success of deleting the cache. ~ so you can introduce the delete cache retry mechanism.

(1) Update database data

(2) failed to delete cache due to various problems

(3) send the key to be deleted to the message queue

(4) consume messages and get the key to be deleted.

(5) continue to retry the delete operation until it is successful

However, this scheme has a drawback, which causes a large number of intrusions into the business line code. So there is scenario 2, in scenario 2, start a subscriber to subscribe to the binlog of the database and get the data you need to operate. In the application, start another program, get the information from this subscriber, and delete the cache.

Read biglog async delete cache

The process is shown in the following figure:

(1) Update database data

(2) the database will write the operation information to the binlog log.

(3) the subscriber extracts the required data and key

(4) create another piece of non-business code to obtain this information

(5) attempted to delete the cache and found that the deletion failed

(6) send this information to the message queue

(7) retrieve the data from the message queue and retry the operation.

Note: the above subscription binlog program has ready-made middleware in mysql * * canal,** can complete the function of subscribing to binlog logs. As for oracle, bloggers don't know if there is ready-made middleware available. In addition, the retry mechanism, the blogger is using the way of message queue. If the requirement for consistency is not very high, just set up another thread in the program and try again every once in a while. Everyone can play these things flexibly and freely, just to provide an idea.

At this point, I believe you have a deeper understanding of "Redis, MySQL cache double write inconsistency how to solve", might as well come to the actual operation! Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report