当前位置:网站首页>How to ensure data consistency between MySQL and redis?
How to ensure data consistency between MySQL and redis?
2022-07-06 13:02:00 【Java misty rain】
Let me just throw the conclusion first : Under the condition of real-time , There is no plan to keep the two completely consistent , Only the final consistency scheme . According to many online solutions , Sum up 6 Kind of , Look directly at the catalog :
Bad plan
1. First write MySQL, To write Redis
Illustration :
This is a sequence diagram , Base note describing the sequence of requests ;
The orange line is a request A, The black line is a request B;
Orange text , yes MySQL and Redis Final inconsistent data ;
Data is from 10 Updated to 11;
All the pictures in the back , That's what it means , I won't repeat .
request A、B They all write first MySQL, And then write Redis, In high concurrency , If you ask for A Writing Redis I was stuck for a while , request B The data update has been completed in turn , There will be problems in the figure .
The picture has been drawn very clearly , I don't have to be wordy anymore , But here's a premise , Is for read requests , Read first Redis, without , Read it again DB, But the read request will not be written back Redis. In plain English , That is, the read request will not be updated Redis.
2. First write Redis, To write MySQL
Same as “ First write MySQL, To write Redis”, Look at the picture and you can understand .
3. Delete first Redis, To write MySQL
This picture is somewhat different from the above , The previous request A and B All update requests , Here's the request A It's an update request , But request B It's a read request , And ask B Your read request will be written back Redis.
request A So let's delete the cache , Maybe because of Caton , The data has not been updated to MySQL, The two data are inconsistent .
The probability of this situation is relatively high , Because request A to update MySQL It may take a long time , The request B The first two steps are both query , It will be very fast .
Good plan
4. Delete first Redis, To write MySQL, And then delete Redis
about “ Delete first Redis, To write MySQL”, If the final inconsistency is to be solved , In fact, no more Redis Just delete it again , This is also what people often say “ Cache double deletion ”.
In order to make it easy for everyone to see the picture , For blue text ,“ Delete cache 10” Must be in “ Write back cache 10” Back , How can we guarantee that it must be in the back ? The first scheme given online is , Make a request A Last deletion of , wait for 500ms.
For this scenario , Just look at it , I can't use it anyway , too Low 了 , The risk is not controllable .
Is there a better plan , I recommend asynchronous serialization deletion , That is, delete the request into the queue
Asynchronous deletion has no effect on online business , Serialization ensures correct deletion in concurrent situations .
What if double deletion fails , Online Redis Add a scheme of cache expiration time , I can't agree with this . I suggest the whole retry mechanism , The retry mechanism of message queue can be used , You can also the whole table by yourself , Record the number of retries , There are many ways .
A brief summary :
“ Cache double deletion ” Don't use mindless sleep 500 ms;
Asynchrony through message queuing & Serial , Achieve the last cache deletion ;
Cache delete failed , Add retry mechanism .
5. First write MySQL, And then delete Redis
For the above situation , For the first query , request B The data queried is 10, however MySQL The data of 11, There is only one inconsistency , For businesses that do not require strong consistency , Can tolerate .( Under what circumstances can it not be tolerated , For example, second kill business 、 Inventory service, etc .)
When requested B When making the second query , Because I missed Redis, Will check again DB, Then write back Reids.
Under what circumstances will there be inconsistencies ? Brother Su is writing 《 How to ensure the consistency of double write between database and cache ?》 It was explained .
Here we need to meet 2 Conditions :
The cache just expires automatically ;
request B From the database 10, Write back cache time consuming , Than request A Write database , And the time to delete the cache is still long .
For the second condition , We all know that updates DB It must take longer than query , So the probability of this happening is very small , It is less likely that the above conditions are met at the same time .
6. First write MySQL, adopt Binlog, Asynchronous update Redis
This program , Mainly monitoring MySQL Of Binlog, And then asynchronously , Update data to Redis, This scheme has a premise , Request for inquiry , Will not write back Redis.
This scheme , To ensure that MySQL and Redis The ultimate consistency of , But if you ask halfway B Need to query data , If there is no data in the cache , Just check it directly DB; If there is data in the cache , The data queried will also be inconsistent .
So this program , Is the ultimate solution to achieve ultimate consistency , But there is no guarantee of real-time .
Several schemes are compared
Let's compare the above discussion 6 Kind of plan :
First write Redis, To write MySQL
This program , I'm sure I won't use , In case DB Hang up , You write data to the cache ,DB No data , This is catastrophic ;
I've seen my classmates use it like this before , If write DB Failure , Yes Redis Reverse operation , What if the reverse operation fails , Do you want to try again ?
First write MySQL, To write Redis
For concurrency 、 Projects with low consistency requirements , That's how many people use it , I used to do this a lot , But it's not recommended ;
When Redis Instant unavailability , Need to call the police , Then deal with it offline .
Delete first Redis, To write MySQL
This way, , I haven't used it yet , Just ignore .
Delete first Redis, To write MySQL, And then delete Redis
It's possible , however It's complicated , We also need to build a message queue to delete asynchronously Redis.
First write MySQL, And then delete Redis
It's recommended , Delete Redis If you fail , You can try again a few more times , Or call the police ;
This scheme , It is the best solution in real-time , In some high concurrency scenarios , Recommend this .
First write MySQL, adopt Binlog, Asynchronous update Redis
For remote disaster recovery 、 Data aggregation, etc , It is suggested that this way , such as binlog + kafka, The consistency of data can also reach the second level ;
Pure high concurrency scenario , This scheme is not recommended , For example, rush to buy 、 Second kill, etc .
Personal conclusion :
Real time consistency scheme : use “ First write MySQL, And then delete Redis” The strategy of , Although there will be inconsistencies between the two , But the conditions to be met are a little harsh , So it is under the condition of real-time , The optimal solution that can satisfy the consistency as much as possible .
The final consistency plan : use “ First write MySQL, adopt Binlog, Asynchronous update Redis”, Can pass Binlog, Asynchronous update with message queue Redis, Is the optimal solution of the final consistency .
It is better to believe in books than to have no books , Because of limited personal ability , There are inevitably omissions and mistakes , If found bug Or better advice , Welcome criticism and correction , Thank you very much .
If this article helps you , Don't forget to give me a 3 even , give the thumbs-up , forward , Comment on ,
I'll see you next time ! How to get answers : Liked Commented Closed ~
Learn more knowledge and skills , Follow up with private bloggers (03)
边栏推荐
- [algorithm] sword finger offer2 golang interview question 2: binary addition
- FairyGUI簡單背包的制作
- 【GNSS数据处理】赫尔默特(helmert)方差分量估计解析及代码实现
- 阿里云一面:并发场景下的底层细节 - 伪共享问题
- 121 distributed interview questions and answers
- Exception: ioexception:stream closed
- FairyGUI增益BUFF數值改變的顯示
- Problems and solutions of robust estimation in rtklib single point location spp
- Mysql database reports an error: row size too large (> 8126) Changing some columns to TEXT or BLOB or using ROW_ FORMAT=DY
- Error: symbol not found
猜你喜欢
微信小程序开发心得
[算法] 剑指offer2 golang 面试题12:左右两边子数组的和相等
Combination of fairygui check box and progress bar
FairyGUI按钮动效的混用
堆排序【手写小根堆】
FairyGUI循环列表
Heap sort [handwritten small root heap]
Office prompts that your license is not genuine pop-up box solution
FairyGUI增益BUFF數值改變的顯示
[algorithm] sword finger offer2 golang interview question 8: the shortest subarray with a sum greater than or equal to K
随机推荐
WSL common commands
Combination of fairygui check box and progress bar
Fairygui gain buff value change display
Affichage du changement de valeur du Buff de gain de l'interface graphique de défaillance
Fairygui character status Popup
FairyGUI条子家族(滚动条,滑动条,进度条)
FairyGUI增益BUFF數值改變的顯示
Agile development helps me
[GNSS data processing] Helmert variance component estimation analysis and code implementation
341. Flatten nested list iterator
Containers and Devops: container based Devops delivery pipeline
FairyGUI人物状态弹窗
RTKLIB: demo5 b34f. 1 vs b33
Heap sort [handwritten small root heap]
FairyGUI循環列錶
Special palindromes of daily practice of Blue Bridge Cup
Fundamentals of UD decomposition of KF UD decomposition [1]
【GNSS】抗差估计(稳健估计)原理及程序实现
Mixed use of fairygui button dynamics
[algorithm] sword finger offer2 golang interview question 9: subarray with product less than k