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


相关文章
|
11天前
|
存储 Java 数据库连接
时序数据库TDengine 3.3.5.0 发布:高并发支持与增量备份功能引领新升级
TDengine 3.3.5.0 版本正式发布,带来多项更新与优化。新特性包括提升 MQTT 稳定性和高并发性能、新增 taosX 增量备份与恢复、支持 JDBC 和 Rust 连接器 STMT2 接口、灵活配置 Grafana Dashboard 等。性能优化涵盖查询内存管控、多级存储迁移、强密码策略等,全面提升时序数据管理的效率和可靠性。欢迎下载体验并提出宝贵意见。
25 5
|
10天前
|
存储 缓存 NoSQL
云端问道21期方案教学-应对高并发,利用云数据库 Tair(兼容 Redis®*)缓存实现极速响应
云端问道21期方案教学-应对高并发,利用云数据库 Tair(兼容 Redis®*)缓存实现极速响应
|
10天前
|
缓存 NoSQL 关系型数据库
云端问道21期实操教学-应对高并发,利用云数据库 Tair(兼容 Redis®)缓存实现极速响应
本文介绍了如何通过云端问道21期实操教学,利用云数据库 Tair(兼容 Redis®)缓存实现高并发场景下的极速响应。主要内容分为四部分:方案概览、部署准备、一键部署和完成及清理。方案概览中,展示了如何使用 Redis 提升业务性能,降低响应时间;部署准备介绍了账号注册与充值步骤;一键部署详细讲解了创建 ECS、RDS 和 Redis 实例的过程;最后,通过对比测试验证了 Redis 缓存的有效性,并指导用户清理资源以避免额外费用。
|
29天前
|
缓存 NoSQL Serverless
云数据库Tair:从稳定低延时缓存到 Serverless KV
本次分享聚焦云数据库Tair的使用,涵盖三部分内容:1) Tair概览,介绍其作为稳定低延时缓存及KV数据库服务的特点和优势;2) 稳定低延迟缓存技术,探讨如何通过多线程处理、优化内核等手段提升性能与稳定性;3) 从缓存到Serverless KV的演进,特别是在AI大模型时代,Tair如何助力在线服务和推理缓存加速。Tair在兼容性、性能优化、扩缩容及AI推理加速方面表现出色,满足不同场景需求。
|
1月前
|
消息中间件 架构师 数据库
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
45岁资深架构师尼恩分享了一篇关于分布式事务的文章,详细解析了如何在10Wqps高并发场景下实现分布式事务。文章从传统单体架构到微服务架构下分布式事务的需求背景出发,介绍了Seata这一开源分布式事务解决方案及其AT和TCC两种模式。随后,文章深入探讨了经典ebay本地消息表方案,以及如何使用RocketMQ消息队列替代数据库表来提高性能和可靠性。尼恩还分享了如何结合延迟消息进行事务数据的定时对账,确保最终一致性。最后,尼恩强调了高端面试中需要准备“高大上”的答案,并提供了多个技术领域的深度学习资料,帮助读者提升技术水平,顺利通过面试。
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
|
1月前
|
缓存 物联网 数据库
InfluxDB vs TDengine :2025 年了,谁家用的数据库还不能高效读缓存?
在工业互联网和物联网的大数据应用场景中,实时数据的写入和查询性能至关重要。如何快速获取最新设备状态并实时处理数据,直接影响到业务的高效运转。本文将深入分析 TDengine 和 InfluxDB 在缓存机制上的差异,帮助读者更好地理解这两款主流时序数据库在性能优化方面的优劣。
136 1
|
2月前
|
缓存 NoSQL 数据库
运用云数据库 Tair 构建缓存为应用提速,完成任务得苹果音响、充电套装等好礼!
本活动将带大家了解云数据库 Tair(兼容 Redis),通过体验构建缓存以提速应用,完成任务,即可领取罗马仕安卓充电套装,限量1000个,先到先得。邀请好友共同参与活动,还可赢取苹果 HomePod mini、小米蓝牙耳机等精美好礼!
|
2月前
|
存储 缓存 数据处理
如何解决数据库高并发问题?
在Web服务框架中加入缓存层,存储高频访问数据,减轻数据库读取负担;增加数据库索引提升查询速度,但需注意索引数量;实施主从读写分离,优化数据处理;对数据库进行拆分,缩小表规模以加快查询;采用分布式架构,有效分散计算压力。
36 0
|
1月前
|
存储 缓存 NoSQL
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
178 85
|
3月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
96 6

热门文章

最新文章

  • 1
    Nginx实现高并发
    95
  • 2
    高并发场景下,到底先更新缓存还是先更新数据库?
    99
  • 3
    Java面试题:解释Java NIO与BIO的区别,以及NIO的优势和应用场景。如何在高并发应用中实现NIO?
    99
  • 4
    Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
    84
  • 5
    Java面试题:如何实现一个线程安全的单例模式,并确保其在高并发环境下的内存管理效率?如何使用CyclicBarrier来实现一个多阶段的数据处理任务,确保所有阶段的数据一致性?
    84
  • 6
    Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
    72
  • 7
    Java面试题:假设你正在开发一个Java后端服务,该服务需要处理高并发的用户请求,并且对内存使用效率有严格的要求,在多线程环境下,如何确保共享资源的线程安全?
    89
  • 8
    在Java中实现高并发的数据访问控制
    56
  • 9
    使用Java构建一个高并发的网络服务
    43
  • 10
    微服务06----Eureka注册中心,微服务的两大服务,订单服务和用户服务,订单服务需要远程调用我们的用,户服务,消费者,如果环境改变,硬编码问题就会随之产生,为了应对高并发,我们可能会部署成一个集
    67