当前位置:网站首页>Data consistency between redis and database
Data consistency between redis and database
2022-07-01 05:05:00 【Cicada bathes in the wind】
official account 「 Cicadas bathe in the wind 」, You are welcome to pay attention to exchanges
Catalog
It is used as a cache when data is read more and written less , Probably Redis Use the most common scenario . When using Redis As a cache , This is the general process .
- If the cache is in Redis in , Cache hit , Then directly return the data

- If Redis There is no corresponding cache in , You need to query the database directly , Then deposit Redis, Finally, return the data to

Usually , We will set a for a cache key value , And aim at key Value to set an expiration time , If the queried data corresponds to key Out of date , Then query the database directly , And store the queried data in Redis, Then reset the expiration time , Finally, return the data to , The pseudocode is as follows :
/** * Get user details according to user name * @author official account 【 Cicadas bathe in the wind 】 */
public User getUserInfo(String userName) {
User user = redisCache.getName("user:" + userName);
if (user != null) {
return user;
}
// Search directly from the database
user = selectUserByUserName(userName);
// Write data to Redis, And set expiration time
redisCache.set("user:" + userName, user, 30000);
// Return the data
return user;
}
Consistency issues
however , stay Redis Of key If the value does not expire , The user has modified his personal information , At this time, we need to operate the database data , Also operate Redis data . Now we have two choices :
- Do it first Redis The data of , Then operate the data of the database
- First operate the data of the database , Then operate Redis The data of
As for which method to choose , Ideally , Either the two operations succeed at the same time , Or fail at the same time , Otherwise, it will appear Redis Inconsistent with the database data .
Unfortunately , At present, there is no framework to guarantee Redis Complete consistency between the data of and the data of the database . We can only take certain measures to reduce the probability of data inconsistency according to the scenario and the code we need to pay , Achieve a compromise between consistency and performance .
Now let's discuss about Redis Some schemes of data consistency between and database .
Options
Delete cache or update cache ?
When the database data changes ,Redis The data also needs to be operated accordingly , So this 「 operation 」 What is to use 「 to update 」 Or use it 「 Delete 」 Well ?
「 to update 」 Call Redis Of set Method , Replace old value with new value ;「 Delete 」 Directly delete the original cache , Re read the database the next time you query , Then update Redis.
Conclusion : Direct use is recommended 「 Delete 」 operation .
Because use 「 to update 」 operation , You will face two choices
Update cache first , Update the database- Update the database first , Update the cache again
The first 1 Don't think about it , Let's talk about it 「 Update the database first , Update the cache again 」 This program .

If the thread 1 And thread 2 Update at the same time , But the execution order of each thread is shown in the figure above , This will lead to inconsistent data , Therefore, from this point of view, we recommend deleting the cache directly .
Besides , Recommended 「 Delete cache 」 There are two other reasons .
- If there are more scenarios of writing database than reading data , Using this scheme will cause the cache to be written frequently , Waste performance ;
- If the cache needs a series of complex calculations to get , So every time you write to the database , It is also a waste of performance to calculate the written cache again .
After clarifying this problem , There are only two choices in front of us :
- Update the database first , Delete the cache
- So let's delete the cache , Update the database
Update the database first , Delete the cache
There may be two exceptions in this way
- Database update failed , At this time, you can catch exceptions through the program , Direct return , No longer delete cache , So there will be no data inconsistency
- Update database successful , Delete cache failed . Cause the database to be the latest data , What's in the cache is old data , Data inconsistency
The first 2 What should we do in this case ? We have two ways : Failure to retry and Asynchronous update .
Failure to retry
If delete cache fails , We can catch this exception , Delete the key Send to message queue . Create a consumer consumption , Try to delete this... Again key, Until the deletion is successful .

There is a drawback to this approach , First, it will invade the business code , Secondly, message queue is introduced , It increases the uncertainty of the system .
Update cache asynchronously
Because when you update the database, you go to binlog Write log in , So we can start a monitor binlog Changing services ( For example, use Ali's canal Open source components ), Then delete it on the client side key The operation of . If the deletion fails , And send it to the message queue .
summary
All in all , In case of cache deletion failure , Our approach is to constantly retry the deletion operation , Until success . Whether it's retry or asynchronous deletion , It's all about ultimate consistency .
So let's delete the cache , Update the database
There may be two exceptions in this way
- Delete cache failed , At this time, you can catch exceptions through the program , Direct return , Do not continue to update the database , So there will be no data inconsistency
- Delete cache succeeded , Database update failed . Data inconsistency may occur in multithreading

At this time ,Redis Old data stored in , The value of the database is new data , Leading to data inconsistency . Now we can use Delay double delete The strategy of , That is, after updating the database data , Delete the cache again .

In pseudocode, that's :
/** * Delay double delete * @author official account 【 Cicadas bathe in the wind 】 */
public void update(String key, Object data) {
// First delete the cache
redisCache.delKey(key);
// Update the database
db.updateData(data);
// Sleep for a while , The time depends on the time taken to read the data
Thread.sleep(500);
// Delete cache again
redisCache.delKey(key);
}
Finally, leave two questions for readers :
- Why?
Update cache first , Update the databaseIt won't work ? - Why should the method of delayed double deletion sleep for a period of time ?
Welcome to comment area .
Recommended reading
official account 「 Cicadas bathe in the wind 」, You are welcome to pay attention to exchanges
边栏推荐
- Principle, technology and implementation scheme of data consistency in distributed database
- FileOutPutStream
- Buffer stream and transform stream
- Global and Chinese markets of InGaAs APD arrays 2022-2028: Research Report on technology, participants, trends, market size and share
- Solution: thread 1:[< *> setvalue:forundefined key]: this class is not key value coding compliant for the key*
- Manually implement a simple stack
- Global and Chinese market of mainboard 2022-2028: Research Report on technology, participants, trends, market size and share
- 手动实现一个简单的栈
- Global and Chinese market of 3D design and modeling software 2022-2028: Research Report on technology, participants, trends, market size and share
- Pytorch neural network construction template
猜你喜欢

导电滑环短路的原因以及应对措施

STM32 expansion board digital tube display

技术分享| 融合调度中的广播功能设计

Single page application

Manually implement a simple stack

STM32 光敏电阻传感器&两路AD采集

Neural network convolution layer

Principle, technology and implementation scheme of data consistency in distributed database

STM32扩展版 按键扫描

Leetcode522- longest special sequence ii- hash table - String - double pointer
随机推荐
Distributed - summary list
工业导电滑环的应用
Global and Chinese market for kitchen range hoods 2022-2028: Research Report on technology, participants, trends, market size and share
FileInputStream
Data loading and preprocessing
【暑期每日一题】洛谷 P5740【深基7.例9】最厉害的学生
对象的序列化与反序列化
打印流与System.setout();
Query long transaction
Global and Chinese market of enterprise wireless LAN 2022-2028: Research Report on technology, participants, trends, market size and share
LeetCode_53(最大子数组和)
RuntimeError: mean(): input dtype should be either floating point or complex dtypes. Got Long instead
[daily question in summer] Luogu p1568 race
手动实现一个简单的栈
JS to solve the problem of floating point multiplication precision loss
点赞的云函数
Quelques outils dont les chiens scientifiques pourraient avoir besoin
Global and Chinese markets of superconductor 2022-2028: Research Report on technology, participants, trends, market size and share
Several methods of creating thread classes
Solve the problem that the external chain file of Qiankun sub application cannot be obtained