高并发先操作数据库,还是先操作缓存?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数据才删除缓存


目录
打赏
0
0
0
0
585
分享
相关文章
【YashanDB知识库】OM仲裁节点故障后手工切换方案和yasom仲裁重新部署后重新纳管数据库集群方案
本文介绍了主备数据库集群的部署、OM仲裁故障切换及重新纳管的全过程。首先通过解压软件包并调整安装参数完成数据库集群部署,接着说明了在OM仲裁故障时的手动切换方案,包括关闭自动切换开关、登录备节点执行切换命令。最后详细描述了搭建新的yasom仲裁节点以重新纳管数据库集群的步骤,如生成配置文件、初始化进程、执行托管命令等,确保新旧系统无缝衔接,保障数据服务稳定性。
如何用Pyppeteer打造高并发无头浏览器采集方案
本文从电商行业数据采集痛点出发,结合 Pyppeteer 高并发无头浏览器技术,打造可配置代理的高效采集方案。通过爬虫代理突破 IP 限制,模拟真实用户行为,实现 Amazon 特价商品数据的稳定抓取与分析。代码示例详细展示了代理集成、并发控制及数据处理流程,实验验证效率提升超 4 倍。该方案助力商业决策、竞品分析,并支持技术扩展与创新应用。
105 13
如何用Pyppeteer打造高并发无头浏览器采集方案
|
2月前
|
redis分布式锁在高并发场景下的方案设计与性能提升
本文探讨了Redis分布式锁在主从架构下失效的问题及其解决方案。首先通过CAP理论分析,Redis遵循AP原则,导致锁可能失效。针对此问题,提出两种解决方案:Zookeeper分布式锁(追求CP一致性)和Redlock算法(基于多个Redis实例提升可靠性)。文章还讨论了可能遇到的“坑”,如加从节点引发超卖问题、建议Redis节点数为奇数以及持久化策略对锁的影响。最后,从性能优化角度出发,介绍了减少锁粒度和分段锁的策略,并结合实际场景(如下单重复提交、支付与取消订单冲突)展示了分布式锁的应用方法。
157 3
WordPress数据库查询缓存插件
这款插件通过将MySQL查询结果缓存至文件、Redis或Memcached,加速页面加载。它专为未登录用户优化,支持跨页面缓存,不影响其他功能,且可与其他缓存插件兼容。相比传统页面缓存,它仅缓存数据库查询结果,保留动态功能如阅读量更新。提供三种缓存方式选择,有效提升网站性能。
84 1
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
定期备份数据库:基于 Shell 脚本的自动化方案
本篇文章分享一个简单的 Shell 脚本,用于定期备份 MySQL 数据库,并自动将备份传输到远程服务器,帮助防止数据丢失。
【SQL技术】不同数据库引擎 SQL 优化方案剖析
不同数据库系统(MySQL、PostgreSQL、Doris、Hive)的SQL优化策略。存储引擎特点、SQL执行流程及常见操作(如条件查询、排序、聚合函数)的优化方法。针对各数据库,索引使用、分区裁剪、谓词下推等技术,并提供了具体的SQL示例。通用的SQL调优技巧,如避免使用`COUNT(DISTINCT)`、减少小文件问题、慎重使用`SELECT *`等。通过合理选择和应用这些优化策略,可以显著提升数据库查询性能和系统稳定性。
155 9
【YashanDB 知识库】OM 仲裁节点故障后手工切换方案和 yasom 仲裁重新部署后重新纳管数据库集群方案
本文介绍了一主一备数据库集群的部署步骤。首先在OM节点上传并解压软件包至指定路径,随后通过调整安装参数、执行安装和集群部署完成数据库设置。接着,在主备节点分别配置环境变量,并查看数据库状态以确认安装成功。最后,针对OM仲裁故障提供了手动切换方案,包括构造故障场景、关闭自动切换开关及使用SQL命令进行主备切换,确保系统高可用性。
云端问道21期方案教学-应对高并发,利用云数据库 Tair(兼容 Redis®*)缓存实现极速响应
云端问道21期方案教学-应对高并发,利用云数据库 Tair(兼容 Redis®*)缓存实现极速响应
161 1
数据库运维:mysql 数据库迁移方法-mysqldump
本文介绍了MySQL数据库迁移的方法与技巧,重点探讨了数据量大小对迁移方式的影响。对于10GB以下的小型数据库,推荐使用mysqldump进行逻辑导出和source导入;10GB以上可考虑mydumper与myloader工具;100GB以上则建议物理迁移。文中还提供了统计数据库及表空间大小的SQL语句,并讲解了如何使用mysqldump导出存储过程、函数和数据结构。通过结合实际应用场景选择合适的工具与方法,可实现高效的数据迁移。
126 1

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等