1.Cache aside pattern

This is the most classic cache + database read and write mode, the operation is as follows: (1) read the cache first, cache does not read the database, and then put the retrieved data into the cache, and return the request response.

② When updating, delete the cache first, and then update the database.

2. Why delete the cache instead of update it?

(1) Because many times, the cache does not simply fetch the value from the data, may need to perform a state replacement, some data calculation, may also need to perform data combination, and so on.

② The 80-20 rule, that is, 20% of the data, occupy 80% of the page view, the updated data, may be unpopular data, can not access for a long time, this will only occupy the cache memory. Lazy thinking: wait until you load data the first time to avoid unnecessary memory and time wasters.

3. The most elementary cache inconsistencies and solutions

Problem: Modify the database first and then delete the cache. If the cache deletion fails, the database and cache data will be inconsistent in the morning. Delete the cache first, then modify the database, if the delete cache succeeded, if the modify database failed, then the database is old data, the cache is empty, then the data will not be inconsistent. The old data in the database is read and then updated to the cache because the cache does not have it at the time of reading

4. Analysis of complex data inconsistency problems

Problem: The data has changed, the cache has been deleted, and the database has not been modified. A request comes in, reads the cache, finds that the cache is empty, queries the database, finds the old data before modification, and puts it in the cache. The data change procedure completes the database modification. This again leads to data inconsistencies

5. Why does this problem occur when hundreds of millions of concurrent traffic flows occur?

This problem can only occur if the data is read or written concurrently.

6. Database and cache update and read operations are asynchronously serialized

To solve the concurrent read and write problem above, consider serializing the update and read operations. (1) When updating data, the operation is routed to a queue within the JVM based on the unique identifier of the data.

(2) When reading data, if it is not found in the cache, then the operation of reading data from the database and the operation of updating the cache will be routed to the same JVM internal queue.

③ A queue corresponds to a worker thread, and the thread retrieves the request from the queue for operation.

So that it can be the same key operation for serialization, a data change operation, performed first, remove the cache, and then to update the database, but haven’t finished the update, if a read request at this time, read the empty cache, you can cache update request is sent to the first in the queue, the backlog in the queue, Then synchronously wait for the cache update to complete.

There is an optimization point here, in a queue, it is meaningless to string multiple update cache requests together, so we can filter. If there is already one update cache request in the queue, then we don’t need to put another update request in the queue, and just wait for the previous update request to complete.

After the worker thread of that queue has finished the database modification of the previous operation, the next operation, the cache update operation, will read the latest value from the database and write it to the cache.

If the request is still in the waiting time range and polling finds that the value can be fetched, it returns directly; If the request waits more than a certain amount of time, the current old value is read directly from the database this time.

7. Problems to be noted in this solution in high concurrency scenarios

(1) Read request block for a long time Because the read request is very slightly asynchronous, you must pay attention to the problem of read timeout. Each read request must be returned within the timeout period. In this solution, the biggest risk is that the data may be updated so frequently that a large number of update operations are backlogged in the queue, and then read requests will have a large number of timeouts, resulting in a large number of requests going directly to the database. Be sure to run some real-world tests to see how frequently data is updated.

② There is also a risk that a large number of read requests will suddenly hang on the service in a delay of tens of milliseconds, depending on whether the service can withstand and how many machines are needed to withstand the peak of the maximum limit. However, not all data are updated at the same time, and the cache is not invalid at the same time. Therefore, the cache of a few data may be invalid every time, and then the corresponding read requests of those data will come, and the concurrency should not be very large.

If multiple instances of the service are deployed, it is necessary to ensure that requests to perform data update operations and cache update operations are routed to the same service instance through the Nginx server.

(4) Routing of hotspot goods. In the event that the number of read/write requests for an item is so high that they all go to the same queue on the same machine, it may cause excessive stress on the same machine. That is, since the cache is only cleared when the item data is updated, and then concurrent reads and writes occur, the problem is not particularly significant if the update frequency is not too high. But it is possible that the load on some machines will be higher.