分布式架构:并发环境下,先操作数据库还是先操作缓存?

10+ 张图解|高并发分布式架构演进 章在介绍一些基本概念后,按照以下过程阐述了整个架构的演进过程: 单机架构 第一次演进:Tomcat 与数据库分开部署 第二次演进:引入本地缓存和分布式缓存 第三次演进:引入反向代理实现负载均衡 第四次演进:数据库读写分离 第五次演进:数据库按业务分库 第六次演进:把大表拆分为小表 第七次演进:使用 LVS 或 F5 来使多个 Nginx 负载均衡 第八次演进:通过 DNS 轮询实现机房间的负载均衡 第九次演进:引入 NoSQL 数据库和搜索引擎等技术 第十次演进:大应用拆分为小应用 阅读详情

推荐阅读:

前言

在分布式系统中,缓存和数据库同时存在时,如果有写操作,先操作数据库还是先操作缓存呢?本文将分5种方案阐述展开对比,谢谢阅读~

缓存维护方案一

如果是一读(线程B)一写(线程A)操作,「先操作缓存,再操作数据库」。流程图如下所示:

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

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

  • 3.线程B发起一个读操作,cache miss缓存失效了。

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

  • 5.线程B执行set cache,把从DB读到的数据,更新到缓存。

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

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

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

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

  • 4.然后老数据设置入cache

  • 5.线程A写入DB最新的数据

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

缓存维护方案二

上个方案是一读一写,如果是双写操作,「先操作缓存,再操作数据库」,会怎么样呢?

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

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

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

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

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

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

  • 2.线程B发起一个写操作,第一步set cache

  • 3.线程B写入数据库到DB

  • 4.线程A写入数据库到DB

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

缓存维护方案三

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

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

  • 2.线程A第二步del cache

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

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

  • 5.线程B同时set cache

「有些朋友可能认为,在第2步删除缓存之前,线程B读过来呢?这时候,读到的是缓存老数据,这个可以认为是正常业务逻辑呀,下次再读取就是正确数据了。」

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

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

缓存维护方案四

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

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

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

缓存维护方案五

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

缓存维护总结

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

  • 1.读取缓存中是否有相关数据
  • 2.如果缓存中有相关数据value,则返回
  • 3.如果缓存中没有相关数据,则从数据库读取相关数据放入缓存中key->value,再返回
  • 4.如果有更新数据,则先更新数据库,再删除缓存
  • 5.为了保证第四步删除缓存成功,使用binlog异步删除
  • 6.如果是主从数据库,binglog取自于从库
  • 7.如果是一主多从,每个从库都要采集binlog,然后消费端收到最后一台binlog数据才删除缓存
大型分布式网站的分布式缓存 高并发环境下,大量的读写请求涌向数据库,磁盘的处理速度与内存显然不在一个量级,从减轻数据库的压力和提高系统响应速度两个角度来考虑,一般都会在数据库之前加一层缓存。由于单台机器的内存资源以及承载能力有限,并且,如果大量使用本地缓存,也会使相同的数据被不同的节点存储多份,对内存资源造成较大的浪费,因此,才催生出了分布式缓存。 Memcache memcache是一款开源的高性能的分 阅读详情

相关推荐

数据库领域数据仓库的高并发处理能力

随着企业数据量的爆炸式增长和实时分析需求的提升,数据仓库系统面临着前所未有的高并发访问压力。本文旨在全面剖析数据仓库在高并发场景下的技术挑战和解决方案,为架构师和开发者提供系统性的指导。本文将首先介绍数据仓库的基本概念和高并发挑战,然后深入探讨核心技术原理,接着通过实际案例展示实现方法,最后讨论未来发展趋势。数据仓库(Data Warehouse): 面向主题的、集成的、相对稳定的、反映历史变化的数据集合,用于支持管理决策高并发(High Concurrency)

2502_91592937的博客 893

5中方案告诉你,并发环境下,先操作数据库还是先操作缓存?

前言 在分布式系统中,缓存和数据库同时存在时,如果有写操作,先操作数据库还是先操作缓存呢?本文将分5种方案阐述展开对比,谢谢阅读~ github地址,衷心感谢每一颗star ❝ https://github.com/whx123/JavaHome ❞ 缓存维护方案一 如果是一读(线程B)一写(线程A)操作,「先操作缓存,再操作数据库」。流程图如下所示: 1.线程A发起一个写操作,第一步del cache 2.线程A第二步写入新数据到DB 3.线程B发起一个读操作,cache miss缓存失效了。 4.线

weiwenhou的博客 395

从golang从GMP模型到分布式架构:无锁化思想的高并发实践

摘要:本文探讨如何借鉴Go语言GMP模型的无锁化思想应对高并发场景。核心思想是通过数据分片和本地缓存将全局竞争转化为局部操作,如将库存分散到多个数据库实例或应用本地内存。针对分布式环境下的扩缩容和故障恢复问题,提出两种方案:中心调度器模式和基于分布式缓存的共享池模式。最终通过分层设计实现高效与可靠的统一,体现了"分而治之"的并发处理智慧。(149字)

ezreal_pan的博客 1156

【sqlbug】mybaties批量执行sql,insert或者update一直无法执行,语句正确,但是就是报错

这种方式最简单,就是用foreach组装成多条update语句,但Mybatis映射文件中的sql语句默认是不支持以";" 结尾的,也就是不支持多条sql语句的执行。所以需要在连接mysql的url上加。

吃素的哈士奇de博客 1487

别再死记硬背了!用51单片机的AD/DA和PWM,亲手做个简易示波器信号发生器

本文详细介绍了如何利用51单片机的PWM和AD/DA功能制作简易示波器信号发生器。通过PWM模拟DAC输出波形,结合XPT2046 ADC进行信号测量,实现方波、三角波和正弦波的生成与显示。项目不仅成本低廉,还能帮助电子爱好者深入理解51单片机的核心功能,是理论与实践结合的绝佳案例。

weixin_28675839的博客 265

利用MobaXterm解密Session密码的实战指南

本文提供了利用MobaXterm解密Session密码的详细实战指南,帮助运维工程师和开发者在忘记密码时找回加密存储的远程连接信息。通过Python脚本和注册表操作,逐步解析MobaXterm的AES加密机制,实现密码解密,并分享安全建议和常见问题解决方案。

weixin_26759093的博客 232

批量执行sql语句时,如何跳过其中发生的错误,继续执行剩下的sql语句,最后在显示所有错误信息

最近,在写项目的时候,遇到这样一个需求,即批量执行数据库授权语句(grant ),当n条授权语句内某一条授权语句,执行失败后,记录其错误信息,然后继续执行剩下的grant 语句,最后在吧错误信息统一抛出。 这里给解决思路: 1.首先,我们需要捕获到sql执行的错误。 try{ jdbc.execute(sql); ...

Wicd的博客 1万+

SigFit实战:从FEA到光学仿真的热力耦合分析全流程解析

在光机系统与芯片封装等精密工程领域,热与力的耦合效应是影响产品性能与可靠性的核心物理问题。有限元分析(FEA)是预测结构在热、力载荷下变形与应力的基础工具,但其结果通常无法直接用于评估光学性能。这需要一座桥梁,将物理场数据转化为光学设计语言。其核心原理在于数据映射与面形表征技术,例如通过泽尼克多项式拟合,将离散的节点位移分解为离焦、像散等标准光学像差。这项技术的工程价值在于,它实现了多物理场仿真的闭环,使工程师能在设计阶段精准预测热变形或应力对波前误差、调制传递函数等关键光学指标的影响。其典型应用场景包括高

weixin_28630185的博客 343

mybatis执行多条sql语句报错

报错在第二条sql语句 解决,在spring.datasource.url配置中添加&allowMultiQueries=true以此允许执行多条sql

whwwycl的博客 906

YOLOv8中的可变形卷积改进 | 从DCNv1到DCNv3的多位置替换可变形卷积保姆级实操

可变形卷积(Deformable Convolution)最早由Dai等人在2017年提出,其核心思想是在标准卷积操作的基础上,引入可学习的偏移量(offsets),使卷积核能够自适应调整其采样位置,从而增强模型对目标变形的感知能力。return x本文通过深入探讨可变形卷积在YOLOv8中的应用,详细介绍了DCNv1、DCNv2和DCNv3的原理和实现,并通过实验验证了其在目标检测任务中的有效性。未来,我们将继续探索更多优化策略和技术,提升YOLOv8模型的性能,以应对更复杂的目标检测任务。

一键难忘的博客 4051

apollo-减速带通行

主车在通过减速带时速度不超过3m/s

是菜鸟o的博客 390

mapper.xml中循环执行多条语句时报错,但是单独拿SQL到数据库却可以执行

mapper.xml中循环执行多条语句时报错,但是单独拿SQL到数据库却可以执行。

98小哥哥的博客 1256

【x265编码器】章节6——x265的码率控制

对于CRF模式而言,右边这部分是是固定值m_rateFactorConstant,在初始化的时候确定,跟分辨率,qCompress这个参数是外部可设参数,默认值0.6,因此QP的选择只跟编码复杂度有关,跟码率无关,编码复杂度越高,QP值越高,因此可以一定程度上说CRF模式是恒定质量的编码模式。其中Complex表示当前帧的编码复杂度,x265中用lookahead模块计算的SATD作为衡量当前帧的复杂度,c为模型参数,qscale是率失真优化中的拉格朗日乘子,R为编码当前帧需要的比特数。

vcvdv123的博客 1万+

Java 架构 19:缓存架构设计(本地缓存 + 分布式缓存)

本文探讨了Java应用中本地缓存与分布式缓存的协同架构设计。通过Caffeine实现高性能本地缓存(微秒级响应),结合Redis构建分布式共享缓存,形成多级缓存防御体系。文章详细介绍了: 缓存价值:降低数据库压力,提升系统吞吐(案例显示性能提升25倍) 架构设计:本地缓存(L1)处理80%请求,Redis(L2)处理19%,数据库仅1% 技术实现: Caffeine集成与智能淘汰策略 Redis部署与Spring Boot整合 完整商品缓存示例代码 监控优化:缓存命中率统计与性能调优建议 适用于中高级开发者

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

英飞凌Tricore问题排查01_Det/Reset/Trap排查宝典

软件跑飞进Det或发生Reset或进Trap了,怎么查?有固定套路可以follow吗?英飞凌Tricore又有哪些专门的定位办法?本篇为您娓娓道来。

initiallizer的博客 4417

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

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

点击上方“Java后端技术”,选择“置顶或者星标”你关注的就是我关心的!微信公众号:捡田螺的小男孩一、前言在分布式系统中,缓存和数据库同时存在时,如果有写操作的时候,先操作数据库还是先操作缓存呢?先思考一下,可能会存在哪些问题,再往下看。下面我分几种方案阐述。二、缓存维护方案一假设有一写(线程A)一读(线程B)操作,先操作缓存,再操作数据库,如下流程图所示:1)线程A发起一个写操作,第一步del ...

Java后端技术 573

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

高并发环境下,先操作数据库还是先操作缓存

前言 在分布式系统中,缓存和数据库同时存在时,如果有写操作的时候,先操作数据库还是先操作缓存呢? 先思考一下,可能会存在哪些问题,再往下看。下面我分几种方案阐述。 缓存维护方案一 假设有一写(线程A)一读(线程B)操作,先操作缓存,在操作数据库,如下流程图所示 1)线程A发起一个写操作,第一步del cache 2)线程A第二步写入新数据到DB 3)线程B发起一个读操作,cach...

曾沂宏的博客 383

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

高并发场景到底是先更新数据库还是先更新缓存?

随着互联网的高速发展,当今时代已然从IT时代进入到DT时代。互联网系统架构也已经由最初的单体架构转变为分布式、微服务架构模式。从数据体量上来看,各系统存储的数据量越来越大,数据的查询性能越来越低。此时,就需要我们不断的进行优化,一种常用的优化手段就是引入缓存。而引入缓存后,我们在向数据库插入数据时,到底是先更新数据库还是先更新缓存呢?

冰河的专栏 1101

缓存基础----本地缓存、分布式缓存以及多级缓存

像MySql等传统的关系型数据库已经不能适用于所有的业务场景,比如电商系统的秒杀场景,APP首页的访问流量高峰场景,很容易造成关系型数据库的瘫痪,随着缓存技术的出现很好的解决了这个问题。 一、缓存的概念(什么是缓存) 缓存就是把访问量较高的热点数据从传统的关系型数据库中加载到内存中,当用户再次访问热点数据时是从内存中加载,减少了对数据库的访问量,解决了高并发场景下容易造成数据库宕机的问题。 二、为什么要用缓存(为什么要用redis作为缓存) 针对于这个问题要从两个方面去考虑,一个是应用系统的高并发.

冰冻非一日之寒 7795

到底是先更新数据库还是先更新缓存?

很多小伙伴最近都在问我,在系统中引入缓存后,当向数据库中写入数据时,是先写数据库还是先写缓存呢?先写数据库和先写缓存有什么区别吗?今天,我们就一起来聊聊这个话题。

冰河的专栏 898

Java并发编程--38-缓存与数据库双写一致性:先删还是先更?延时双删够用吗?

本文探讨了缓存与数据库双写一致性问题,分析了常见方案的优缺点。核心观点包括: Cache-Aside模式是基础方案,通过先更新数据库再删除缓存来保证一致性,但存在短暂不一致窗口 先删缓存再更新数据库的方案会导致严重脏数据问题 延时双删可以缓解但无法彻底解决不一致问题 生产环境推荐使用Canal监听MySQL binlog异步更新缓存的最终一致性方案 文章对比了不同方案的实现原理和适用场景,指出强一致性需要分布式事务,而大多数业务场景可采用最终一致性。最后提供了面试标准答案和选型指南,建议核心数据使用Cana

weisian的博客 3708

【分布式】分布式环境下如何保证数据库和缓存的双写一致性?看完我明白了!!

写在前面 当今时代,互联网高速发展,已然从IT时代进入到DT时代。我们系统的架构也由原来的单体应用,转变为分布式、微服务的架构模式。从数据上来看,数据量越来越大,数据的查询性能越来越低。此时,就需要我们不断的进行优化,一种常用的优化手段就是加入缓存,使用缓存之后,就会带来新的问题:分布式环境下如何保证数据库和缓存的双写一致性?今天,我们就一起来剖析这个问题,并给出相应的解决方案。 如何保证数据一致性? 首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下

冰河的专栏 2187

剑指offer之java缓存总结,从单机缓存到分布式缓存架构

为什么要用缓存(读多写少,高并发) 1、提高读取吞吐量 2、提升应用程序性能 3、降低数据库成本 4、减少后端负载 5、消除数据库热点 6、可预测的性能

隐风的博客 4703

分布式架构 高并发下分布式缓存

目录 1、高并发下分布式缓存实现原理 2、缓存部分的架构思想 3、过滤器的布隆算法实现原理 1、高并发下分布式缓存实现原理 客户端访问数量庞大对于单一的服务器数据库来说会造成很大的开销甚至崩溃,但实现如图所示原理的高并发缓存架构便可有效的解决该问题。 具体实现思路是:首先客户端访问服务器时,服务器先从非关系型数据库Redis里快速查找数据,当数据在缓存了未找到时,再由访问缓存转向访问关系型数据库如mysql,但在此期间不可直接访问需要先通过过滤器,确认该数据的...

qq_50909707的博客 986
上一篇: IntelliJ IDEA 超全优化设置,效率提升杠杠的!
下一篇: Spring Cloud Alibaba 之 Sentinel详解
「已注销」
博客等级 码龄6年 36粉丝 149原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值