Keep the database and redis There are roughly two schemes for data consistency of ：
One ： So let's delete the cache , Update the database
The reason why this plan will lead to inconsistencies is that . There is also a request A Update operation , Another request B Query operation . Then the following will happen :
- 1） request A Write operation , Delete cache
- 2） request B Query found cache does not exist
- 3） request B Go to the database to query for the old value
- 4） request B Write the old value to the cache
- 5） request A Writes the new value to the database
This leads to inconsistencies . and , If you do not use the cache expiration policy , The data is always dirty .
Solution ： Adopt the strategy of delay double deletion
Two ： Update the database first , Delete the cache
Suppose there are two requests , A request A Do query operation , A request B Do update operation , So this is going to happen
- 1） The cache just failed
- 2） request A Query the database , Get an old value
- 3） request B Writes the new value to the database
- 4） request B Delete cache
- 5） request A Writes the old value found to the cache
ok, If this happens , Dirty data does happen
There is a congenital condition for this to happen , It's the steps （3） Write database operations than steps （2） The read database operation takes less time , It's possible to make steps （4） Before the steps （5）. But , Think about it , Database reads are much faster than writes （ Why else do read and write separation , The point of doing read/write separation is because the read operation is faster , Less resources ）, So step （3） It takes more time than steps （2） shorter , It's very difficult for this to happen .
3、 ... and ： The best solution ：
Let me give you an explanation , In theory , Set the expiration time for the cache , Is a solution that guarantees ultimate consistency . Under this scheme , We can set an expiration time for the data stored in the cache , All writes are subject to the database , Just do your best for the cache operation . That is, if the database write succeeds , Cache update failed , So just reach the expiration time , The subsequent read requests will naturally read the new value from the database and backfill the cache .
Redis The data in it is always up to date , But there's a background update task （“ Timing code ” perhaps “ Queue driven code ） Read db, Cram the latest data into Redis. This approach will Redis See as “ Storage ”. Visitors don't know the actual data source behind it , Only know Redis It's the only place where you can get data . When the actual data source is updated , Background update task to update data to Redis. There will still be Redis Inconsistency with the actual data source . If it's a timed mission , The longest inconsistent duration is the execution interval of the update task ; If it's a queue like update , So the inconsistent time depends on the delay of queue generation and consumption . Common queues （ Or equivalent ） Yes Redis（ Why is it still Redis）,Kafka,AMQ,RMQ,binglog,log file , Ali's canal etc. .
Be careful , There is no such thing as the best solution , We choose different solutions for different business scenarios , It's not likely to be perfect