当前位置:网站首页>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
边栏推荐
- 洗个冷水澡吧
- 【FTP】FTP常用命令,持续更新中……
- Basic skeleton of neural network nn Use of moudle
- Global and Chinese market of metal oxide semiconductor field effect transistors 2022-2028: Research Report on technology, participants, trends, market size and share
- [summer daily question] Luogu p5886 Hello, 2020!
- [daily question in summer] Luogu p5740 [deep foundation 7. Example 9] the best student
- Print stream and system setout();
- STM32 extended key scan
- 工业导电滑环的应用
- Daily question -leetcode1175- permutation of prime numbers - Mathematics
猜你喜欢

C read / write application configuration file app exe. Config and display it on the interface

The longest increasing subsequence and its optimal solution, total animal weight problem

STM32扩展板 数码管显示

Neural networks - use sequential to build neural networks

Daily question -leetcode1175- permutation of prime numbers - Mathematics

工业导电滑环的应用

Copier le matériel de conseils de bébé ne peut pas être vide, comment résoudre?

导电滑环使用的注意事项

分布式数据库数据一致性的原理、与技术实现方案

Technology sharing | broadcast function design in integrated dispatching
随机推荐
Global and Chinese markets for soft ferrite cores 2022-2028: Research Report on technology, participants, trends, market size and share
[summer daily question] Luogu p5886 Hello, 2020!
Use of dataloader
pytorch中常用数据集的使用方法
如何选择导电滑环材料
Buffer stream and transform stream
LeetCode1497-检查数组对是否可以被 k 整除-数组-哈希表-计数
LeetCode_ 53 (maximum subarray and)
Quelques outils dont les chiens scientifiques pourraient avoir besoin
Pico neo3 handle grabs objects
1076 Forwards on Weibo
如何开始学剪辑?零基础详细解析
缓冲流与转换流
RuntimeError: “max_pool2d“ not implemented for ‘Long‘
【暑期每日一题】洛谷 P3742 umi的函数
STM32扩展板 数码管显示
LeetCode_ 35 (search insertion position)
Overview of the construction details of Meizhou veterinary laboratory
Data loading and preprocessing
STM32 光敏电阻传感器&两路AD采集