数据库
首页 > 数据库> > 缓存,数据库先操作那个都行

缓存,数据库先操作那个都行

作者:互联网

先更数据库,再删除缓存

问题

缓存删除后,尚未更新数据库,并发读请求,从数据库读到了旧值,并且更新到缓存导致后续请求都是旧值。

 

时间
从上
   到下,
越来
越晚

更新操作

 

删除redis

读取操作

 

缓存没有数据

 

从数据库读到旧值

 

回写redis

更新mysql

返回

返回

 

解决方式

经典的延迟双删。就是:先更新数据线,再删缓存,之后延迟一段时间再删缓存。

时间
从上
   到下,
越来
越晚

更新操作

 

删除redis

读取操作

 

缓存没有数据

 

从数据库读到旧值

 

回写redis

更新mysql

返回

延迟一段时间

 

 

 

删除redis

 

 

读取操作

 

缓存没有数据

 

从数据库读到新值

 

回写redis

 

返回

延迟一段时间,挺重要不能拍脑袋,需要考虑2个因素

考虑查询接口响应时间

时间
从上
   到下,
越来
越晚

更新操作

 

删除redis

读取操作

 

缓存没有数据

 

从数据库读到旧值

更新mysql

 

延迟一段时间,
小于从数据读取数据的时间,
延迟策略失效

 

删除redis

 

 

回写redis

 

返回

考虑mysql主从同步事件

自建mysql集群,配置不当,会出现mysql主从同步延迟大的情况。

 

时间
从上
   到下,
越来
越晚

更新操作

 

删除redis

读取操作

 

缓存没有数据

 

从数据库读到旧值

 

回写redis

更新mysql主库

返回

延迟一段时间,
小于mysql主从同步时间
延迟策略失效

 

 

 

删除redis

读取操作

 

缓存没有数据

 

从库读到旧值

mysql主从同步完成

回写redis

 

返回

延迟时间必须大于查询接口的响应时间。

并且要大于mysql主从同步的时间,防止主从同步延迟造成,读到旧值的情况

                                                                                                     --- 温安适 20210225

先删缓存,再更新数据库

注意:建议查询接口要从主库进行读取

时间
从上
   到下,
越来
越晚

更新操作

 

更新mysql主库

读取操作

 

缓存有数据,读到旧值

删除redis

返回

 

 

 

读取操作

 

缓存没有数据

 

主库读到新值

 

回写redis

 

返回

存在的问题:

等待缓存删除完成,期间数据库会有不一致数据短暂存在,但是一般可以不处理。

总结:

策略

潜在问题

解决方式

注意事项

先删缓存,
再更数据库

并发条件下
数据库更新还没有完成
有并发读请求,从数据库读到了旧值

延迟双删

延迟时间必须
大于查询接口的响应时间。
并且大于mysql主从同步的时间

先更数据库,
再删缓存

并发条件下
缓存没有删除完成,并发读
从缓存读到了旧值

不处理,
最终会一致

查询接口建议读主库,存在不一致,
但是一般不需处理

标签:缓存,数据库,旧值,redis,读到,mysql,都行
来源: https://blog.csdn.net/floor2011/article/details/114070618