高并发下如何保证缓存和数据库的数据一致性?
缓存由于其高性能 , 支持高并发的特性 , 在高并发的项目中不可或缺 。 被大家广泛使用的有Redis , Memcached等 。 本文主要探讨几种常见的缓存的读写模式 , 以及如何来保证缓存和数据库的数据一致性 。
Cache-Aside
Cache-Aside可能是项目中最常见的一种模式 。 它是一种控制逻辑都实现在应用程序中的模式 。 缓存不和数据库直接进行交互 , 而是由应用程序来同时和缓存以及数据库打交道 。 Cache-Aside的名字正体现了这个模式 , Cache在应用的一旁(aside) 。
读数据时
- 程序需要判断缓存中是否已经存在数据 。
- 当缓存中已经存在数据(也就是缓存命中 , cache hit) , 则直接从缓存中返回数据
- 当缓存中不存在数据(也就是缓存未命中 , cache miss) , 则先从数据库里读取数据 , 并且存入缓存 , 然后返回数据
本文插图
写数据时 , 我们可以有以下两种策略:
第一种策略:
- 更新数据库
- 更新缓存
- A写数据库
- B后于A写数据库
- B写缓存
- A写缓存
- 缓存和数据库中的数据不一致 , 缓存中的是脏数据
第二种策略:
- 更新数据库
- 删除缓存中对应的数据
本文插图
那么这种写策略会有线程安全的问题吗?有 , 试想一下有两个线程 , 线程A读 , 线程B写
- A读数据 , 由于未命中那么从数据库中取数据
- B写数据库
- B删除缓存
- A由于网络延迟比较慢 , 将脏数据写入缓存
应用场景
应用于缓存不支持Read-Through/Write-Through的系统 。
优点
- 缓存仅仅保存被请求的数据 , 属于懒加载模式(Lazy Loading) , 和下文的Write-Through模式相比 , 避免了任何数据都被写入缓存造成缓存频繁的更新 。
- 当发生缓存未命中的情况时 , 则会比较慢 , 因为要经过三个步骤:查询缓存 , 从数据库读取 , 写入缓存 。
- 复杂的逻辑都在应用程序中 , 如果实现微服务 , 多个微服务中会有重复的逻辑代码
这种模式中 , 应用程序将缓存作为主要的数据源 , 而数据库对于应用程序是透明的 , 更新数据库和从数据库的读取的任务都交给缓存来代理了 , 所以对于应用程序来说 , 简单很多 。
Read-Through
由缓存配置一个读模块 , 它知道如何将数据库中的数据写入缓存 。 在数据被请求的时候 , 如果未命中 , 则将数据从数据库载入缓存 。
本文插图
Write-Through
缓存配置一个写模块 , 它知道如何将数据写入数据库 。 当应用要写入数据时 , 缓存会先存储数据 , 并调用写模块将数据写入数据库 。
【高并发下如何保证缓存和数据库的数据一致性?】
推荐阅读
- 电脑数码精通|夏季如何让电脑的故障率降到最低?早知道早做准备吧
- |支付宝面试题:如果你是支付宝的产品经理,如何让更多人用支付宝点外卖?
- |传统互联网产品经理正在消失,如何自救?
- 华南科技第一线|京东618,大学生换5G新机如何选?
- 毒草科技|如何挑选入门级智能录音笔?搜狗C1对比讯飞A1,谁更值得买?
- cnBetaTB|看机器人如何制作出既有颜值又美味的蛋饼
- 京东京东沃尔玛再加持,达达募资3亿美元如何应战即时配送?
- 电视提前锁定618电视圈“爆款”海信激光电视是如何做到的?
- 淘宝|如何在淘宝网上开网店?在淘宝网上开店有什么要求?
- 摩盒网|电商平台的网页如何更佳吸引人