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


相关文章
|
4月前
|
缓存 并行计算 监控
vLLM 性能优化实战:批处理、量化与缓存配置方案
本文深入解析vLLM高性能部署实践,揭秘如何通过continuous batching、PagedAttention与前缀缓存提升吞吐;详解批处理、量化、并发参数调优,助力实现高TPS与低延迟平衡,真正发挥vLLM生产级潜力。
1031 0
vLLM 性能优化实战:批处理、量化与缓存配置方案
|
5月前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
|
5月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
923 5
|
6月前
|
缓存 运维 安全
WordPress安全加速:Cloudflare + Nginx缓存优化方案
本文介绍如何通过Cloudflare与Nginx优化WordPress网站性能,涵盖静态资源长期缓存、动态页面智能缓存及敏感路径保护,提升加载速度并保障后台安全。适用于使用Cloudflare与Nginx环境的WordPress站点。
326 0
|
9月前
|
数据采集 Web App开发 监控
如何用Pyppeteer打造高并发无头浏览器采集方案
本文从电商行业数据采集痛点出发,结合 Pyppeteer 高并发无头浏览器技术,打造可配置代理的高效采集方案。通过爬虫代理突破 IP 限制,模拟真实用户行为,实现 Amazon 特价商品数据的稳定抓取与分析。代码示例详细展示了代理集成、并发控制及数据处理流程,实验验证效率提升超 4 倍。该方案助力商业决策、竞品分析,并支持技术扩展与创新应用。
344 13
如何用Pyppeteer打造高并发无头浏览器采集方案
|
9月前
|
NoSQL 算法 安全
redis分布式锁在高并发场景下的方案设计与性能提升
本文探讨了Redis分布式锁在主从架构下失效的问题及其解决方案。首先通过CAP理论分析,Redis遵循AP原则,导致锁可能失效。针对此问题,提出两种解决方案:Zookeeper分布式锁(追求CP一致性)和Redlock算法(基于多个Redis实例提升可靠性)。文章还讨论了可能遇到的“坑”,如加从节点引发超卖问题、建议Redis节点数为奇数以及持久化策略对锁的影响。最后,从性能优化角度出发,介绍了减少锁粒度和分段锁的策略,并结合实际场景(如下单重复提交、支付与取消订单冲突)展示了分布式锁的应用方法。
734 3
|
11月前
|
缓存 NoSQL 关系型数据库
WordPress数据库查询缓存插件
这款插件通过将MySQL查询结果缓存至文件、Redis或Memcached,加速页面加载。它专为未登录用户优化,支持跨页面缓存,不影响其他功能,且可与其他缓存插件兼容。相比传统页面缓存,它仅缓存数据库查询结果,保留动态功能如阅读量更新。提供三种缓存方式选择,有效提升网站性能。
221 1
|
11月前
|
消息中间件 缓存 NoSQL
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
|
存储 缓存 NoSQL
云端问道21期方案教学-应对高并发,利用云数据库 Tair(兼容 Redis®*)缓存实现极速响应
云端问道21期方案教学-应对高并发,利用云数据库 Tair(兼容 Redis®*)缓存实现极速响应
377 1
|
缓存 NoSQL 关系型数据库
云端问道21期实操教学-应对高并发,利用云数据库 Tair(兼容 Redis®)缓存实现极速响应
本文介绍了如何通过云端问道21期实操教学,利用云数据库 Tair(兼容 Redis®)缓存实现高并发场景下的极速响应。主要内容分为四部分:方案概览、部署准备、一键部署和完成及清理。方案概览中,展示了如何使用 Redis 提升业务性能,降低响应时间;部署准备介绍了账号注册与充值步骤;一键部署详细讲解了创建 ECS、RDS 和 Redis 实例的过程;最后,通过对比测试验证了 Redis 缓存的有效性,并指导用户清理资源以避免额外费用。
299 1

热门文章

最新文章