Redis study concluded (13) - the distributed database and cache coherence scheme to resolve the double write!

First, why write this article?

First, the cache due to its high concurrency and high performance characteristics, has been widely used in the project. In terms of read cache, nothing we doubt the figure below are in accordance with the process to carry out business operations:

Write pictures described here

But in terms of updating the cache, to finish updating the database, it is updating the cache, or delete the cache? Or is to delete the cache, and then update the database? In fact, it remains highly controversial. There is no one comprehensive blog, these different kinds of programs to parse, so bloggers in fear, we braved the risk of being sprayed, wrote this article.

Second, the structure of the article

1, to explain the policy cache update;

2, disadvantages of each strategy analysis;

3, are given for the shortcomings of refinement;

Third, the text

Do a description, in theory, to set the cache expiration time, it is to ensure the consistency of the final solution. In this program, we can set the expiration time for the cached data, all writes to the database prevail, the operation of the cache can only do our best. This means that if the database write successful cache update failed, then once they reach the expiration time, the subsequent read request will naturally read the new values from the database and then backfill the cache. Therefore, the following discussion of ideas does not depend on the cache settings to the expiration of this program. Here, we discuss three update policies: 1, to update the database, and then update the cache; 2, to delete the cache, and then update the database; 3, first update the database, and then delete the cache. No one should ask me, why did not update the cache first, and then update the database this strategy!

Fourth, to update the database, and then update the cache

This program, everyone is widespread opposition, and why? The following two reasons:

One reason, thread-safe angle

Request while A and B update operation request, then there will be:

1. A thread update the database;

2, thread B updates the database;

3, thread B updated its cache;

4. Thread A updates the cache;

A request to update the cache which appeared to be early fishes than B request to update the cache, but because the network reasons, B earlier than A cache is updated. This leads to dirty data, and therefore do not consider!

Second reason, business scenarios angle

There are the following two points:

(1) If you are writing a database scenario more, and read data scene is relatively small business needs, using this program will lead to, are they not read data, the cache will be updated frequently, waste performance.

(2) If you write the value of the database, not directly write cache, but to go through a series of complex calculations re-write cache. So, after each write to the database, the calculated values ​​are written to the cache again, no doubt a waste of performance. Clearly, delete the cache is more suitable.

The next discussion is the most controversial, first delete the cache, and then update the database. Or to update the database, and then delete the cache problem.

Fifth, first delete the cache, and then update the database

The reason for this inconsistency is that the program can cause: A request for a simultaneous update, query operation B is another request. Then it will appear the following situations:

(1) A request for a write operation, delete the cache;

(2) discovery cache query request B is absent;

(3) B a request to a database query to obtain the old value;

(4) a request to write buffer old value B;

(5) A request for a new value written to the database;

The above situation will lead to inconsistencies. Moreover, if the cache is not used to set the expiration time of the policy, the data is always dirty.

So, how to solve it? Using delay tactics double deleted! Pseudo-code as follows:

Write pictures described here

Translated into Chinese is the description:

(1) out of the first cache;

(2) write a database (same as the original and the two steps);

(3) Sleep 1 second, again out of the buffer;

To do so, can be cached dirty data in 1 second caused by the deletion again!

5.1, then this one second how determined the specific sleep how long?

For the above case, the reader should evaluate their own time-consuming to read data business logic of their own projects. Then write data at sleep time consuming basis of the read data on the business logic, you can add a few hundred ms. The purpose of doing so is to ensure that the end of the read requests, write requests can delete cached read requests caused by dirty data.

5.2, if you use MySQL to read and write separation architecture how to do?

The OK, in this case, as the cause of inconsistent data, or two requests, one request for an update operation A, the other B requests query operation.

(1) A request for a write operation, delete the cache;

(2) A request to write data to the database;

(3) the query request buffer B was found, no value buffer;

(4) B to query requests from the library, this time, the master-slave synchronization is not yet complete, so that the old value to the query;

(5) The write cache requests the old value B;

(6) database master-slave synchronization is completed, the new value changed from the library;

The above-mentioned circumstances, is the reason for inconsistent data. Or double deletion delay tactics. But, as modified sleep time in a master-slave synchronization on the basis of the delay time, plus a few hundred ms.

5.3, out of sync with this strategy, reduce throughput how to do?

ok, then the second delete as asynchronous. Yourself a thread, asynchronous delete. Thus, the written request would not sleep after a period of time, and then return. To do so, to increase throughput.

5.4 second. If deletion fails how to do?

This is a very good question, because the second deletion failed, a situation will arise. There are two requests, one request for an update operation A, the other B requests query operation, for convenience, assume that a single library:

(1) A request for a write operation, delete the cache;

(2) discovery cache query request B is absent;

(3) B a request to a database query to obtain the old value;

(4) a request to write buffer old value B;

(5) A request for a new value written to the database;

(6) A request to try to write to a cache removal request B value, and failed; ok, that is to say. If the second failure delete cache, cache and database problems occur again inconsistent.

5.5, how to solve it?

Specific solutions, let me see Section VI resolve bloggers to update policy!

Sixth, to update the database, and then delete the cache

First, let's talk about. Foreigners made a cache update routine, called "Cache-Aside pattern". Which pointed out:

  • Failure : access to data cache start application, we did not get access to data from the database, after successfully into the cache;

  • Hit : application access to data from the cache, after taking a return;

  • Updated : put data into the database, after the success, let a cache miss;

In addition, the social networking site facebook is also well-known paper "Scaling Memcache at Facebook" proposed, they are also used to update the database, and then delete the cached policy.

6.1, concurrency issues this situation does not exist?

no. Assuming that there will be two requests to do a query request A, B a request to do an update operation, then a situation will be generated:

(1) cache just fail;

(2) A request to query a database to obtain an old value;

(3) B requests a new value written to the database;

(4) removal of the cached request B;

(5) A request to the old value found in the write cache;

ok, if this happens, really dirty data will occur.

6.2, however, the probability of this happening and how many?

Above situation there is a congenital condition that 6.1 in step (3) database write operation than in step (2) to read and less time consuming database operations, possible that step (4) prior to step (5). However, we think, read speed much faster than the database write operations (or else why do read and write separation, separate read and write it is to make sense because the read operation faster, consume less resources), and therefore step (3) shorter than the time-consuming step (2), this situation is difficult to appear.

Assume that someone have to bicker, obsessive-compulsive disorder, must resolve how to do?

6.3, how to solve the concurrency problem?

First, to set the buffer time is an effective program. Secondly, the policy 2 (to delete the cache, and then update the database) asynchronous given in the delay removal policy to ensure that after reading the request is complete, then delete it.

6.4, there are other causes inconsistencies it?

Yes, this is the Cache Update Policy 2 (first delete the cache, and then update the database) and cache update policy 3 (first update the database, and then delete the cached) there is a problem, delete the cache fails if how to do, it is not there inconsistencies it. For example, a request to write data, and then written to the database, and delete the cache fails, it will appear on the inconsistencies. This is the Cache Update Policy 2 (first delete the cache, and then update the database) the last question has left.

6.5, how to solve?

Provides a safeguard mechanism to retry, here are two options.

Option One:

Flow is as follows:

Write pictures described here

(1) update the database data;

(2) delete the cache because of the problems of failure;

(3) The key to be deleted is transmitted to the message queue;

(4) self-consumption message, get to be deleted key;

(5) continue to retry the delete operation until it succeeds;

However, this solution has the disadvantage of causing a large number of service lines intrusion code. So with Option II, in the second scheme, the subscription program to start a subscription database binlog, acquire necessary operation. In the application, the other from a program, access to information coming from this subscription program, delete cache operation.

Option II:

Process as shown below:

Write pictures described here

(1) update the database data;

(2) the operation information database will be written to the log which binlog;

(3) Feed program extracts the desired data, and Key;

(4) a new paragraph non-business code, obtain the information;

(5) try to remove the cache operation, found that deletion fails;

(6) to send the information to a message queue;

(7) the data retrieved from the message queue, retry the operation;

Remarks: The above procedures have an existing subscription binlog middleware called the canal, can be done to subscribe binlog log function in mysql. As for the oracle, bloggers do not currently know whether there are ready-made middleware can be used. Further, the retry mechanism, is the use of the blogger message queue manner. If the consistency requirement is not very high, directly in the program from another thread, from time to time to retry to, these flexible it can play freely, just a thought.

Seven summary

This article is actually the current Internet has the consistency of the program, carried out a summary. For the update policy to delete the cache, and then update the database, as well as the proposed scheme maintains a memory queue way, bloggers looked at, that realization is very complex, it is not necessary, it is not necessary given in the text. Finally, I hope you gain something.

Guess you like

Origin blog.csdn.net/u012562943/article/details/93200547
Recommended