数据库和缓存数据如何保障一致性(四种方案)
四种方案列举及分析
方案一:同步删除
核心流程:
- 首先更新数据库数据
- 然后删除缓存数据
存在问题:
- 存在部分成功:更新数据库及删除缓存非原子操作,缓存删除失败会存在脏数据
- 难以收拢所有数据库更新入口:入口如更新API接口,数据库管理平台,直接命令行操作等
- 并发场景下存在问题
- 竞态条件: 在多个线程或进程同时访问和删除缓存数据时,可能会出现竞态条件。例如,当多个线程同时检查缓存中的数据是否存在,并且都发现需要进行删除操作时,就会导致多个线程同时执行删除操作,可能出现数据不一致的情况。
- 脏读问题: 在删除缓存数据时,如果其他线程在删除操作完成之前读取到了已经被删除的数据,就会导致脏读问题。这可能会导致数据的错误使用或显示。
- 写回问题: 在缓存同步删除的过程中,由于并发访问的存在,可能会发生写回问题。即,在数据删除操作执行完成之前,其他线程或进程又将该数据写入了缓存。这样,即使原本应该被删除的数据被重新写入缓存,导致删除操作被无效化。
并发回写场景示例:
线程1 | 线程2 |
---|---|
查询数据库数据:a=1 | |
更新数据库:a=2 | |
删除缓存数据 | |
将数据写入缓存:a=1 |
小结:由于存在更新入口难以收拢,并发脏数据等问题,此方案一般不会单独使用,可作为补充
方案二:延迟双删
核心流程:
- 删除缓存数据
- 更新数据库数据
- 等待一小段时间
- 再次删除缓存数据
存在的问题:
- 延迟时间不好确定
时间太短,可能达不到删除脏缓存的效果,时间长的话,这个中间产生脏数据的可能就会变大 - 无法绝对保障数据的一致性
线程1 | 线程2 | 线程3 |
---|---|---|
删除缓存数据 | ||
更新主库:a=2 | ||
再次删除缓存 | ||
查询从数据库:a=1 | ||
将数据写入缓存:a=1(脏) | ||
数据同步从库:a=2 |
此例中,由于数据库主从同步完成之间,存在并发请求,从而导致脏数据,脏数据还可能持续很久。
同时,当主库写压力过大时,主从之间的同步延迟可能是分钟级的。
因此,方案存在明显问题,一般也不会直接使用
小结:由于延迟时间不好确定,同时无法绝对保障数据的一致性,该方案一般也不会使用
方案三:异步监听binglog删除+重试
核心流程:
- 更新数据库
- 监听binlog删除缓存
- 缓存删除失败则通过MQ不断重试,直到删除成功
存在问题:
- 整体执行链路相比同步删除变的更长,脏数据产生的窗口时间拉大
- 增加了对其他组件的依赖,健壮性相比同步删除变的更差一点
小结:大多数场景下使用没有问题,业务较小的场景比较合适,或可以按需进行继续改造
三种方案综合评价
方案 | 问题 | 优点 |
---|---|---|
方案一:同步删除 | 1. 删除缓存失败存在脏数据 2. 难以收拢所有更新数据库数据入口 3. 并发场景下脏数据问题 |
实现简单 |
方案二:延迟双删 | 1.延迟时间不好确定 2.无法绝对保障数据的一致性 |
相比同步删除进一步减少了脏数据的可能 |
方案三:异步监听binglog删除+重试 | 1. 整体执行链路相比同步删除变的更长,脏数据产生的窗口时间拉大。 2. 增加了对其他组件的依赖,健壮性相比同步删除变的更差一点 |
问题不明显,适合大多数业务场景 |
终极方案
核心流程:
1. 删除数据库同步删除缓存:
缩小可能发生脏数据的时间窗
2. Binlog + MQ删除缓存:
兜底所有入口,避免遗漏删除缓存场景,同时通过MQ的消息重试保证缓存一定删除成功
3. 监听Binlog延迟N秒进行数据一致性校验:
每个更新操作后延迟校验数据库与缓存的一致性,异常则修复,解决极端场景下的脏数据问题
4. 过期删除缓存:
刚更新过的缓存存在不一致性的概率相对会大很多,因此可以在更新场景下设置更小的过期时间
5. 存在数据库更新的链路禁用缓存:
因为数据库更新后,立刻查询缓存,缓存可能还没来的及更新,此时可直接查询数据库降低读脏数据风险
6. 【集群问题】强制读Redis主节点:
更新Redis后,立刻读取,如果读的是从节点,可能数据不是最新的,此时可强制读主节点降低读脏数据风险
7. 【监控分析】查询异步数据一致性校验:
查询完数据库之后,通过线程池再异步的查一次缓存,将数据库数据和缓存数据做比较,结果进行打点统计,如果概率超1%说明流程还不可靠,需分析不一致性数据,分析原因,继续优化。如果概率小于0.01%,证明流量基本可靠。
8. 【灰度放量】新方案试点后再逐步放开:
没有经过线上验证的方案,不要全切,让风险可控,逐步放开
设计流程图:
总结:高并发场景下缓存与数据库数据的一致性问题,最终还是要看实际项目运行情况,以选择不同方案,并持续优化,每种方案都有自己的考量
本篇文章参考:https://blog.csdn.net/v123411739/article/details/124237900

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)