缓存和数据一致性问题
2021-09-24 20:51:38 小德 访问次数 145

一、简单的缓存引入方式

1、数据库的数据全量刷入缓存,不设置失效时间

2、写请求只更新数据库,不更新缓存

3、定时任务,定时刷全量数据库的数据,更新到缓存中

优点:所有数据都能命中缓存,效率很高

缺点:缓存利用率低,不访问的数据一直在缓存中

         数据不一致,取决于定时任务的执行频率

适合场景:体量小,对数据一致性要求不高的业务场景

二、缓存利用率和一致性问题

1、提高缓存利用率,写只写数据库,读请求,先读缓存,如果缓存不存在则从数据库读并且更新缓存,并且写入缓存的数据都设置失效时间;

2、数据变更时同时更新缓存;

3、更新缓存两个顺序:

            先更新数据库 再更新缓存: 

            先更新缓存 再更新数据库:  缓存成功,数据库更新

            更新缓存 + 更新数据库 会把没有访问的记录也存入缓存中 浪费内存

            引入 删除缓存的机制 不更新缓存 删除的方式  读 先读DB  再更新缓存 提高利用率

4、删除缓存的顺序

        先删缓存 后更新库  不一致 

        先更新数据库  再删缓存   保证数据一致性 数据库写是加锁的  

        保证第二步成功 :失败往往重试也是失败  失败记录扔消息队列 异步重试  消息队列保证可靠性,消息队列成功投递

5、其他方案   订阅数据库变更日志binlog 再操作缓存(删除缓存)  阿里的canal

结论:推荐使用 先更新数据库 再删除缓存 配合消息队列 活订阅变更日志 

6、读写分离+主从延迟带来的缓存种了旧值的问题  延迟双删 二次删除记录队列  延迟时间 大于主从复制的延迟时间

三、思想      

    1、性能和一致性满足的平衡,通常业务考虑做到数据最终一致的方案

    2、核心问题:缓存利用率 +并发 + 缓存和数据库一起成功

    3、失败场景重试:异步重试

    4、订阅变更日志的思想:本质把MySQL当做Leader副本 其他缓存系统当做Follower副本,通过同步变更日志的方式保证 leader  和 Follower 之间的一致