缓存删除后,尚未更新数据库,并发读请求,从数据库读到了旧值,并且更新到缓存导致后续请求都是旧值。
时间从上 到下,越来越晚 | 更新操作 | |
---|---|---|
删除redis | 读取操作 | |
缓存没有数据 | ||
从数据库读到旧值 | ||
回写redis | ||
更新mysql | 返回 | |
返回 |
经典的延迟双删。就是:先更新数据线,再删缓存,之后延迟一段时间再删缓存。
时间从上 到下,越来越晚 | 更新操作 | |
---|---|---|
删除redis | 读取操作 | |
缓存没有数据 | ||
从数据库读到旧值 | ||
回写redis | ||
更新mysql | 返回 | |
延迟一段时间 | ||
删除redis | ||
读取操作 | ||
缓存没有数据 | ||
从数据库读到新值 | ||
回写redis | ||
返回 |
延迟一段时间,挺重要不能拍脑袋,需要考虑2个因素
时间从上 到下,越来越晚 | 更新操作 | |
---|---|---|
删除redis | 读取操作 | |
缓存没有数据 | ||
从数据库读到旧值 | ||
更新mysql | ||
延迟一段时间,小于从数据读取数据的时间,延迟策略失效 | ||
删除redis | ||
回写redis | ||
返回 |
自建mysql集群,配置不当,会出现mysql主从同步延迟大的情况。
时间从上 到下,越来越晚 | 更新操作 | |
---|---|---|
删除redis | 读取操作 | |
缓存没有数据 | ||
从数据库读到旧值 | ||
回写redis | ||
更新mysql主库 | 返回 | |
延迟一段时间,小于mysql主从同步时间延迟策略失效 | ||
删除redis | 读取操作 | |
缓存没有数据 | ||
从库读到旧值 | ||
mysql主从同步完成 | 回写redis | |
返回 |
延迟时间必须大于查询接口的响应时间。 并且要大于mysql主从同步的时间,防止主从同步延迟造成,读到旧值的情况 --- 温安适 20210225
注意:建议查询接口要从主库进行读取
时间从上 到下,越来越晚 | 更新操作 | |
---|---|---|
更新mysql主库 | 读取操作 | |
缓存有数据,读到旧值 | ||
删除redis | 返回 | |
读取操作 | ||
缓存没有数据 | ||
主库读到新值 | ||
回写redis | ||
返回 |
等待缓存删除完成,期间数据库会有不一致数据短暂存在,但是一般可以不处理。
策略 | 潜在问题 | 解决方式 | 注意事项 |
---|---|---|---|
先删缓存,再更数据库 | 并发条件下数据库更新还没有完成有并发读请求,从数据库读到了旧值 | 延迟双删 | 延迟时间必须大于查询接口的响应时间。并且大于mysql主从同步的时间 |
先更数据库,再删缓存 | 并发条件下缓存没有删除完成,并发读从缓存读到了旧值 | 不处理,最终会一致 | 查询接口建议读主库,存在不一致,但是一般不需处理 |
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。