首先考虑为什么出现了不一致?
可能存在的情况:
1.主,从同步延迟[主要原因]
2. 缓存与数据库双写有失败的情形.
出现这种情况的原因是什么?
逃不开CAP法则
分布式造成的. 都是分布式惹的祸. 操作了主库,也操作从库[可以这么理解:调用可主库写,主库有同步从库,间接操作从库] ;
操作缓存,也操作了数据库; 不能保证中间被查询了.被修改了.
这些都不是原子性操作,不能保证原子性操作就会出现不一致的现象.
其实解决方案都可参照 Java内存模型中原子性,可见性,有序性来出方案.
分布式理论中有个CAP法则,就是一致性,可靠性,分区冗余只能保证其中两个 CA CP AP,
保证强一致性,就需要牺牲可用性
解决方案:
强一致性的解决方案: 就需要牺牲可用性.
1.主从模式下 :要想主从一致.
a.从库没有同步完之前,我不提供服务,[降低可用性];
b.主从不一致, 要想强一致, 那就读主库,[间接的还是视为从库不可用]
2.缓存与数据库不一致,
两种方案:
第一:延时双删. 删缓存, 写库, 再删缓存.
第二: 更新数据库, 删除缓存,
但是还是有漏洞啊;
case1 删除缓存,----> 写库[还没写完]----> 读脏数据到缓存,----> 再删缓存, 在第二次删之前 都是脏数据在缓存.
case2 更新数据库,-->[未更新完]----> 读脏数据---->删除缓存 [删除失败怎么办? 😁 ]--->重试😋?---重试失败怎办 😋?
两个都不完美. 有完美方案吗? 没有, 但是你就想拿到一致的数据, 怎么办?
降低可用性. 如何降低? 保证我在操作的时候,别人不能动, 一动也不能动, ------>加锁.
==写操作====>|| 加锁---->淘汰缓存,--->写数据库---->释放锁---->
==读操作====>|| 判断锁有没有释放--->读缓存或者数据库---->
这样肯定能保证原子性了,也就保证读到数据都是一致的,但是高并发,牺牲了可用性.
3,事务的一致性方案,
写操作----->写数据到A库,------>写数据到B库----->完成逻辑.
这个怎么保证一致性呢, 现在2PC,TCC就是牺牲了可用性来保证一致性的, CP原则.
这也是两阶段提交,不是特别流行的一个原因吧, 高并发性能不高,
其实分布式中一致性,可用性, 缓存一致性, 都是在从CAP原则中找折中方案.
解题思路就是:
可以参考锁, volatile是怎么保证可见性 原子性
BASE理论. CAP理论
以上都是个人见解,欢迎前来吐槽,喷我.