数据库和缓存一致性
数据库和缓存一致性
方案一: 先更新数据库 后更新缓存
并发问题
- A修改数据库为1
- B修改数据库为2;修改缓存为2
- A修改缓存为1; 这就导致数据库缓存不一致了
Title:并发更新数据和缓存问题
participant 请求1
participant 请求2
participant 缓存
participant 数据库
请求1->数据库: 更新为1
请求2-->数据库: 更新为2
请求2-->缓存: 更新为2
请求1->缓存: 更新为1
Note right of 缓存: 缓存和数据最终不一致
方案二: 先更新缓存 后更新数据库
并发问题
Title:并发更新数据和缓存问题
participant 请求1
participant 请求2
participant 缓存
participant 数据库
请求1->缓存: 更新为1
请求2-->缓存: 更新为2
请求2-->数据库: 更新为2
请求1->数据库: 更新为1
Note right of 缓存: 缓存和数据最终不一致
方案三:先删除缓存 再更新数据库
读写并发导致不一致
participant 请求1
participant 请求2
participant 缓存
participant 数据库
请求1->缓存: 删除缓存
请求2-->缓存: 查询 没命中
请求2-->数据库: 查询数据库值为2
请求2-->缓存: 缓存值为2
请求1->数据库: 更新为1
Note right of 缓存: 缓存和数据最终不一致
优化方案 延迟双删
participant 请求1
participant 请求2
participant 缓存
participant 数据库
请求1->缓存: 删除缓存
请求2-->缓存: 查询 没命中
请求2-->数据库: 查询数据库值为2
请求2-->缓存: 缓存值为2
请求1->数据库: 更新为1
Note over 缓存: sleep一会再删除缓存 确保查询结束
请求1->缓存: 删除缓存
Note right of 缓存: 缓存和数据最终一致
方案四:先更新数据库 再删除缓存
读写并发导致不一致。 这中情况很少出现。因为查询比更新快很多
participant 请求1
participant 请求2
participant 缓存
participant 数据库
请求1->缓存: 查询 没命中
请求1->数据库: 查询数据库值为1
请求2-->数据库: 更新数据库2
请求2-->缓存: 删除缓存
请求1->缓存: 更新为1
Note right of 缓存: 缓存和数据最终不一致
删除缓存失败 如何保证成功呢
- 方法1: 重试机制 MQ保证
- 方法2:订阅mysql Binlog 阿里的canal中间件