当前位置:网站首页>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)

边栏推荐
- Problems and solutions of robust estimation in rtklib single point location spp
- Edit distance (multi-source BFS)
- KF UD decomposition pseudo code implementation advanced [2]
- Mysql database index
- 使用rtknavi进行RT-PPP测试
- 基于rtklib源码进行片上移植的思路分享
- Knowledge system of digital IT practitioners | software development methods -- agile
- Detailed explanation of balanced binary tree is easy to understand
- 堆排序【手写小根堆】
- 第一人称视角的角色移动
猜你喜欢
![[算法] 剑指offer2 golang 面试题1:整数除法](/img/e6/f17135207b3540ec58e5a9eed54220.png)
[算法] 剑指offer2 golang 面试题1:整数除法
![[算法] 剑指offer2 golang 面试题10:和为k的子数组](/img/63/7422489d09a64ec9f0e79378761bf1.png)
[算法] 剑指offer2 golang 面试题10:和为k的子数组
![[algorithm] sword finger offer2 golang interview question 6: sum of two numbers in the sorting array](/img/d5/4bda133498f71ae9fd7a64c6cba8f0.png)
[algorithm] sword finger offer2 golang interview question 6: sum of two numbers in the sorting array

使用rtknavi进行RT-PPP测试

一文搞定 UDP 和 TCP 高频面试题!

Record: the solution of MySQL denial of access when CMD starts for the first time

Problems and solutions of robust estimation in rtklib single point location spp
![[算法] 剑指offer2 golang 面试题4:只出现一次的数字](/img/f7/23ffc81ec8e9161c15d863c1a67916.png)
[算法] 剑指offer2 golang 面试题4:只出现一次的数字

Halcon knowledge: gray_ Tophat transform and bottom cap transform

FairyGUI增益BUFF數值改變的顯示
随机推荐
Meanings and differences of PV, UV, IP, VV, CV
Agile development helps me
KF UD decomposition pseudo code implementation advanced [2]
【GNSS】抗差估计(稳健估计)原理及程序实现
Fgui project packaging and Publishing & importing unity & the way to display the UI
MySQL error warning: a long semaphore wait
KF UD分解之UD分解基础篇【1】
Acwing-116 pilot brother
[algorithm] sword finger offer2 golang interview question 4: numbers that appear only once
[rtklib] preliminary practice of using robust adaptive Kalman filter under RTK
Mixed use of fairygui button dynamics
微信小程序开发心得
Lean product development - Lean Software Development & lean product development
FairyGUI人物状态弹窗
[algorithm] sword finger offer2 golang interview question 12: the sum of the left and right sub arrays is equal
FairyGUI按钮动效的混用
isEmpty 和 isBlank 的用法区别
面试必备:聊聊分布式锁的多种实现!
MySQL 三万字精华总结 + 面试100 问,吊打面试官绰绰有余(收藏系列
基本Dos命令