双写一致性问题如何解决
大前提
先读缓存,如果缓存中没有的情况下,才从数据库中读取
更新策略
1、先更新缓存,再更新数据库(不可取)
2、先更新数据库,再更新缓存(不可取)
3、先删除缓存,再更新数据库(不可取)
4、先更新数据库,再删缓存(可取,有问题)
1、先更新缓存,再更新数据库
这种情况下,如果说先更新缓存然后更新数据库失败,那么读到的数据就是错误的数据
2、先更新数据库,再更新缓存
对于这种情况
假设有两个线程A.B同时进行更新操作,
(1)线程A更新了数据库
(2)线程B更新了数据库
(3)线程B更新了缓存
(4)线程A更新了缓存
这种出现请求A更新缓存应该比B 要更新的早,但是因为网络的原因,B先更新缓存,这就导致了脏数据,因此不考虑
3、先删除缓存,再更新数据库
这种情况下会发生如下:
假设有两个线程A,B
(1)线程A请求写的操作,首先删除了缓存
(2)线程B来查询发现缓存没有
(3)线程B到数据库中读取,由于此时线程A还没有进行写的动作,所以B读到的就是旧值,B又将自己读到的写入缓存中
(4)线程A将新值写入数据库
对于这种,可以采用延时双删策略
(1)先淘汰缓存
(2)再写数据库(这两步和原来一样)
(3)休眠一秒,再淘汰缓存
这么一秒内所造成的脏数据再次删除
4、先更新数据库,再删缓存
最好的办法,但是也存在并发问题
比如说两个请求A,B A做查询操作,B做更新操作,会发生如下情况
(1)缓存刚好失效
(2)A查询数据库得到了一个旧值
(3)请求B将新值写入数据库
(4)请求B删除缓存
(5)请求A将读到的旧值写入缓存
发生这种情况的概率有多少
步骤三的写数据库比步骤二的读数据库时间更短,才有可能让步骤四先与步骤五,但是一般情况下数据库的读操作远快于数据库的写操作,因此这一情况下很难出现