当前位置:网站首页>Redis cache data consistency solution analysis

Redis cache data consistency solution analysis

2022-06-26 04:05:00 Dreamers on the road

The article brief introduction

Redis As a non relational database , It has been applied in various high performance business scenarios .Redis It's a database based on the nature of memory , Therefore, it has very good performance in reading and writing , In actual use , Most of them are also used for business data caching .

Design to cache , We have to consider a situation , It's the consistency of the cache data . How to understand cache consistency ? Let's take a simple example , In an e-commerce system application , We store the inventory quantity of goods in the cache , At this time, we update the inventory quantity of goods in the background , How to ensure that the inventory information in the cache is updated synchronously without the problem of inventory quantity ? In the end of the article, I'll show you the code , This case is also used as a demonstration .

Cache design

Before you learn about cache design , Let's take a look at the picture below . This is also a design pattern for many caching systems .

 picture

  1. The client sends the request to the server . Go directly to the cache to query the data .
  2. If there is data in the cache , Then it is directly returned to the data in the client cache .
  3. If there is no data in the cache , Then query the database .
  4. according to MySQL Data queried in , Write to cache and return to client .

The main idea of the article

Data consistency mentioned earlier in this article , refer to MySQL How to keep up with the data in the cache . The following article also analyzes how to realize data synchronization .

Update strategy

Cache first, then database

 picture

Strategy statement

  1. There is an update request on the back end , Update the corresponding Redis cache . You can delete it directly in the process , Write again ; It can also be updated . It's easier to use delete .
  2. If the cache update fails , Return the client error message directly .
  3. If the cache update is successful , Then update MySQL operation .
  4. If MySQL Update failed , Then roll back the entire update , Including update operations in the cache .

Problem analysis

  1. If in the first place 1 Delete cache used in , When the first 2 Failed to update cache in , At this time, you need to manually append the cache , Otherwise Cache breakdown situation , This situation is very serious .
  2. In the 4 in , to update MySQL In case of failure , Will roll back the data in the cache . If it's updating MySQL In operation , New request from client , At this point, the client reads the new data , But in reality MySQL The update failed , It's impossible for users to read new data , In this way, the data will be inconsistent .

Code demonstration

// Redis Connection object 
$redis = null;
// MySQL Connection object 
$mysql = null;
//  Client request parameters 
$requestParams = [];
//  Delete cache 
$updateRedis = $redis->del('key');
if ($updateRedis) {
  //  to update MySQL
  $updateMysql = $mysql->update('update xxx set a=xx where id=xxx');
  if ($updateMysql) {
    return ' Data update failed ';
  }
// Rollback cache ( Due to cache delete failure , There is no need to roll back manually at this point . If it's an executive update Redis, You also need to roll back manually Redis)
  $redis->set('key', $requestParams);
}
return ' Cache update failed ';

First database and then cache

 picture

Strategy statement

  1. The client initiates an update request , To update MySQL.
  2. MySQL After the update is successful , Then update the cache . Update cache can use delete operation directly , You can also specify updates .
  3. If Redis If the update fails, the client information will be returned .

Problem analysis

  1. This strategy can clearly see that , Updating MySQL The stage is OK .MySQL If it fails, it will return to the client directly and the update fails , There's no need to manipulate the cache .
  2. But when updating the cache , If the cache update fails , however MySQL The data in is updated successfully . So we are faced with this problem , Is it rolling back or not doing anything ?
  3. If the first 2 in , Operation cache failed , Without any processing, the cache will always be old data , Unless the cache is valid .

Code demonstration

// Redis Connection object 
$redis = null;
// MySQL Connection object 
$mysql = null;
//  Client request parameters 
$requestParams = [];
//  to update MySQL
$updateMysql = $mysql->update('update xxx set a=xx where id=xxx');
if ($updateMysql) {
  //  Update cache 
  $updateRedis = $redis->set($requestParams);
  if ($updateRedis) {
    return ' Data updated successfully ';
  }
  return ' Cache update failed ';
}
return ' Data update failed ';

Multithreading synchronization

 picture

Strategy statement

  1. Client initiates request , At this point, two threads are created .
  2. One thread execution MySQL to update , A thread performs cache updates .
  3. If one of the two threads fails , Then roll back the entire update operation .

Problem analysis

  1. This strategy updates data through multiple threads , Reduce congestion problems , Speed up program processing .
  2. If MySQL Thread update speed failed and processing speed is slow ,Redis The update is successful and the processing speed is fast . Do a rollback at this point , In a more detailed process , New requests get new data from the cache , After the rollback, the cached data is the old data .

Code demonstration

// Redis Connection object 
$redis = null;
// MySQL Connection object 
$mysql = null;
//  Client request parameters 
$requestParams = [];
//  Thread one update MySQL
$updateMysql = $mysql->update('update xxx set a=xx where id=xxx');
//  Thread 2 update cache 
$updateRedis = $redis->set('key', $requestParams);
if ($updateMysql && $updateRedis) {
  return ' Data updated successfully ';
}
//  Perform data rollback 
.....
return ' Data update failed ';

Lock processing

 picture

Strategy statement

  1. Client initiates request , Create a lock .
  2. At this point, update in turn MySQL And cache data .
  3. No matter success or failure , Release the lock after execution .

Problem analysis

  1. Client initiates request , Create a lock . When creating locks , have access to set-nx The way , Avoid service hang up, cache will not automatically expire .
  2. to update MySQL And cache data .
  3. If the cache succeeds, the lock is released , If the cache fails, the lock is released .
  4. This method is suitable for data High consistency The situation of , For example, when the back end initiates a request , The client can't read , Release the lock until the write operation succeeds or fails .
  5. Use this method , The client needs to read the code to judge the lock situation . If there is a lock, it is in the waiting state . Not suitable for high concurrency business scenarios . But it ensures that the data is completely consistent .

Code demonstration

// Redis Connection object 
$redis = null;
// MySQL Connection object 
$mysql = null;
//  Client request parameters 
$requestParams = [];
/  The client initiates a lock request 
//  to update MySQL
$updateMysql = $mysql->update('update xxx set a=xx where id=xxx');
$updateRedis = $redis->set('key', $requestParams);
if ($updateMysql && $updateRedis) {
  //  Release the lock 
  //  Return information 
  return ' Data updated successfully ';
}
//  Release the lock 
//  Return information 
return ' Update failed ';

Article summary

This article is an analysis of different situations . In many cases, it's just a theoretical state . Compare recommended methods , It is recommended to update first MySQL Updating cache .

Link to the original text :https://mp.weixin.qq.com/s/GdM3VrL8-pEXBLmDi_paZA

原网站

版权声明
本文为[Dreamers on the road]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202180539489609.html