高并发先操作数据库,还是先操作缓存?5 个方案告诉你!

简介: 在分布式系统中,缓存和数据库同时存在时,如果有写操作的时候,先操作数据库还是先操作缓存呢?先思考一下,可能会存在哪些问题,再往下看。下面我分几种方案阐述。

前言

在分布式系统中,缓存和数据库同时存在时,如果有写操作的时候,先操作数据库还是先操作缓存呢?


先思考一下,可能会存在哪些问题,再往下看。下面我分几种方案阐述。


缓存维护方案一

假设有一写(线程A)一读(线程B)操作,先操作缓存,在操作数据库,如下流程图所示

image.png



1)线程A发起一个写操作,第一步del cache


2)线程A第二步写入新数据到DB


3)线程B发起一个读操作,cache miss,


4)线程B从DB获取最新数据


5)请求B同时set cache


这样看,没啥问题。我们再看第二个流程图,如下:


image.png


1)线程A发起一个写操作,第一步del cache


2)此时线程B发起一个读操作,cache miss


3)线程B继续读DB,读出来一个老数据


4)然后老数据入cache


5)线程A写入了最新的数据


OK,酱紫,就有问题了吧,老数据入到缓存了,每次读都是老数据啦,缓存与数据与数据库数据不一致。


缓存维护方案二

双写操作,先操作缓存,在操作数据库。


image.png


1)线程A发起一个写操作,第一步set cache


2)线程A第二步写入新数据到DB


3)线程B发起一个写操作,set cache,


4)线程B第二步写入新数据到DB


这样看,也没啥问题。,但是有时候可能事与愿违,我们再看第二个流程图,如下:


image.png


1)线程A发起一个写操作,第一步set cache


2)线程B发起一个写操作,第一步setcache


3)线程B写入数据库到DB


4)线程A写入数据库到DB


执行完后,缓存保存的是B操作后的数据,数据库是A操作后的数据,缓存和数据库数据不一致。


缓存维护方案三

一写(线程A)一读(线程B)操作,先操作数据库,再操作缓存。


image.png


1)线程A发起一个写操作,第一步write DB


2)线程A第二步del cache


3)线程B发起一个读操作,cache miss


4)线程B从DB获取最新数据


5)线程B同时set cache


这种方案没有明显的并发问题,但是有可能步骤二删除缓存失败,虽然概率比较小,优于方案一和方案二,平时工作中也是使用方案三。


综上对比,我们一般采用方案三,但是有没有完美全解决方案三的弊端的方法呢?


缓存维护方案四

这个是方案三的改进方案,都是先操作数据库再操作缓存,我们来看一下流程图:


image.png


通过数据库的binlog来异步淘汰key,以mysql为例,可以使用阿里的canal将binlog日志采集发送到MQ队列里面,然后通过ACK机制确认处理 这条更新消息,删除缓存,保证数据缓存一致性。


但是呢还有个问题,如果是主从数据库呢?


缓存维护方案五

主从DB问题:因为主从DB同步存在同时延时时间如果删除缓存之后,数据同步到备库之前已经有请求过来时,会从备库中读到脏数据,如何解决呢?


解决方案如下流程图:


image.png


缓存维护总结

综上所述,在分布式系统中,缓存和数据库同时存在时,如果有写操作的时候,先操作数据库,再操作缓存。如下:


(1)读取缓存中是否有相关数据


(2)如果缓存中有相关数据value,则返回


(3)如果缓存中没有相关数据,则从数据库读取相关数据放入缓存中key->value,再返回


(4)如果有更新数据,则先更新数据,再删除缓存


(5)为了保证第四步删除缓存成功,使用binlog异步删除


(6)如果是主从数据库,binglog取自于从库


(7)如果是一主多从,每个从库都要采集binlog,然后消费端收到最后一台binlog数据才删除缓存


相关文章
|
18天前
|
消息中间件 canal 缓存
项目实战:一步步实现高效缓存与数据库的数据一致性方案
Hello,大家好!我是热爱分享技术的小米。今天探讨在个人项目中如何保证数据一致性,尤其是在缓存与数据库同步时面临的挑战。文中介绍了常见的CacheAside模式,以及结合消息队列和请求串行化的方法,确保数据一致性。通过不同方案的分析,希望能给大家带来启发。如果你对这些技术感兴趣,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!
52 6
项目实战:一步步实现高效缓存与数据库的数据一致性方案
|
25天前
|
canal 缓存 NoSQL
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
根据对一致性的要求程度,提出多种解决方案:同步删除、同步删除+可靠消息、延时双删、异步监听+可靠消息、多重保障方案
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
|
2月前
|
消息中间件 缓存 监控
如何保证缓存和数据库的一致性?
保证缓存和数据库的一致性的做法
|
2月前
|
存储 机器学习/深度学习 自然语言处理
LangChain与向量数据库:高效的信息检索方案
【8月更文第4天】随着自然语言处理技术的发展,特别是深度学习的进步,我们能够更加高效地处理大量的文本数据。LangChain 作为一种强大的工具链,旨在简化和加速构建复杂的自然语言处理应用程序。结合向量数据库,LangChain 可以实现高效且精准的信息检索功能。本文将探讨这一组合的工作原理,并通过一个具体的实现案例来展示其在实际应用中的效果。
293 2
|
25天前
|
存储 SQL 关系型数据库
一篇文章搞懂MySQL的分库分表,从拆分场景、目标评估、拆分方案、不停机迁移、一致性补偿等方面详细阐述MySQL数据库的分库分表方案
MySQL如何进行分库分表、数据迁移?从相关概念、使用场景、拆分方式、分表字段选择、数据一致性校验等角度阐述MySQL数据库的分库分表方案。
109 14
一篇文章搞懂MySQL的分库分表,从拆分场景、目标评估、拆分方案、不停机迁移、一致性补偿等方面详细阐述MySQL数据库的分库分表方案
|
9天前
|
消息中间件 缓存 NoSQL
15)如何保证缓存和数据库之间的数据一致性
15)如何保证缓存和数据库之间的数据一致性
20 1
|
2月前
|
消息中间件 负载均衡 应用服务中间件
高并发环境下的Nginx整合方案
【8月更文挑战第20天】在高并发环境下,整合Nginx代理服务器、静态文件服务器、Tomcat集群、Mycat数据库读写分离和消息队列,可以构建一个强大、灵活且可扩展的Web服务架构。
33 1
|
2月前
|
缓存 NoSQL Redis
一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)
这篇文章是关于Java面试中可能会遇到的五个问题,包括MySQL索引类型及其对数据库性能的影响、Redis的RDB和AOF持久化机制、Redis的过期键删除策略、Redis的单线程模型为何高效,以及缓存雪崩、缓存穿透和缓存击穿的概念及其解决方案。
|
2月前
|
存储 缓存 关系型数据库
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
37 0
|
2月前
|
存储 缓存 NoSQL
基于SpringBoot+Redis解决缓存与数据库一致性、缓存穿透、缓存雪崩、缓存击穿问题
这篇文章讨论了在使用SpringBoot和Redis时如何解决缓存与数据库一致性问题、缓存穿透、缓存雪崩和缓存击穿问题,并提供了相应的解决策略和示例代码。
65 0