本文主要讨论这么几个问题:
(1)“缓存与数据库”需求缘起
(2)“淘汰缓存”还是“更新缓存”
(3)缓存和数据库的操作时序
(4)缓存和数据库架构简析
一、需求缘起
场景介绍
缓存是一种提高系统读性能的常见技术,对于读多写少的应用场景,我们经常使用缓存来进行优化。
例如对于用户的余额信息表account(uid, money),业务上的需求是:
(1)查询用户的余额,SELECT money FROM account WHERE uid=XXX,占99%的请求
(2)更改用户余额,UPDATE account SET money=XXX WHERE uid=XXX,占1%的请求
由于大部分的请求是查询,我们在缓存中建立uid到money的键值对,能够极大降低数据库的压力。
读操作流程
有了数据库和缓存两个地方存放数据之后(uid->money),每当需要读取相关数据时(money),操作流程一般是这样的:
(1)读取缓存中是否有相关数据,uid->money
(2)如果缓存中有相关数据money,则返回【这就是所谓的数据命中“hit”】
(3)如果缓存中没有相关数据money,则从数据库读取相关数据money【这就是所谓的数据未命中“miss”】,放入缓存中uid->money,再返回
缓存的命中率 = 命中缓存请求个数/总缓存访问请求个数 = hit/(hit+miss)
上面举例的余额场景,99%的读,1%的写,这个缓存的命中率是非常高的,会在95%以上。
那么问题来了
当数据money发生变化的时候:
(1)是更新缓存中的数据,还是淘汰缓存中的数据呢?
(2)是先操纵数据库中的数据再操纵缓存中的数据,还是先操纵缓存中的数据再操纵数据库中的数据呢?
(3)缓存与数据库的操作,在架构上是否有优化的空间呢?
这是本文关注的三个核心问题。
二、更新缓存 VS 淘汰缓存
什么是更新缓存:数据不但写入数据库,还会写入缓存
什么是淘汰缓存:数据只会写入数据库,不会写入缓存,只会把数据淘汰掉
更新缓存的优点:缓存不会增加一次miss,命中率高
淘汰缓存的优点:简单(我去,更新缓存我也觉得很简单呀,楼主你太敷衍了吧)
那到底是选择更新缓存还是淘汰缓存呢,主要取决于“更新缓存的复杂度”。
例如,上述场景,只是简单的把余额money设置成一个值,那么:
(1)淘汰缓存的操作为deleteCache(uid)
(2)更新缓存的操作为setCache(uid, money)
更新缓存的代价很小,此时我们应该更倾向于更新缓存,以保证更高的缓存命中率
如果余额是通过很复杂的数据计算得出来的,例如业务上除了账户表account,还有商品表product,折扣表discount
account(uid, money)
product(pid, type, price, pinfo)
discount(type, zhekou)
业务场景是用户买了一个商品product,这个商品的价格是price,这个商品从属于type类商品,type类商品在做促销活动要打折扣zhekou,购买了商品过后,这个余额的计算就复杂了,需要:
(1)先把商品的品类,价格取出来:SELECT type, price FROM product WHERE pid=XXX
(2)再把这个品类的折扣取出来:SELECT zhekou FROM discount WHERE type=XXX
(3)再把原有余额从缓存中查询出来money = getCache(uid)
(4)再把新的余额写入到缓存中去setCache(uid, money-price*zhekou)
更新缓存的代价很大,此时我们应该更倾向于淘汰缓存。
however,淘汰缓存操作简单,并且带来的副作用只是增加了一次cache miss,建议作为通用的处理方式。
三、先操作数据库 vs 先操作缓存
OK,当写操作发生时,假设淘汰缓存作为对缓存通用的处理方式,又面临两种抉择:
(1)先写数据库,再淘汰缓存
(2)先淘汰缓存,再写数据库
究竟采用哪种时序呢?
还记得在《冗余表如何保证数据一致性》文章(点击查看)里“究竟先写正表还是先写反表”的结论么?
对于一个不能保证事务性的操作,一定涉及“哪个任务先做,哪个任务后做”的问题,解决这个问题的方向是:
如果出现不一致,谁先做对业务的影响较小,就谁先执行。
由于写数据库与淘汰缓存不能保证原子性,谁先谁后同样要遵循上述原则。
假设先写数据库,再淘汰缓存:第一步写数据库操作成功,第二步淘汰缓存失败,则会出现DB中是新数据,Cache中是旧数据,数据不一致。
假设先淘汰缓存,再写数据库:第一步淘汰缓存成功,第二步写数据库失败,则只会引发一次Cache miss。
结论:数据和缓存的操作时序,结论是清楚的:先淘汰缓存,再写数据库。
四、缓存架构优化
上述缓存架构有一个缺点:业务方需要同时关注缓存与DB,有没有进一步的优化空间呢?有两种常见的方案,一种主流方案,一种非主流方案(一家之言,勿拍)。
主流优化方案是服务化:加入一个服务层,向上游提供帅气的数据访问接口,向上游屏蔽底层数据存储的细节,这样业务线不需要关注数据是来自于cache还是DB。
非主流方案是异步缓存更新:业务线所有的写操作都走数据库,所有的读操作都总缓存,由一个异步的工具来做数据库与缓存之间数据的同步,具体细节是:
(1)要有一个init cache的过程,将需要缓存的数据全量写入cache
(2)如果DB有写操作,异步更新程序读取binlog,更新cache
在(1)和(2)的合作下,cache中有全部的数据,这样:
(a)业务线读cache,一定能够hit(很短的时间内,可能有脏数据),无需关注数据库
(b)业务线写DB,cache中能得到异步更新,无需关注缓存
这样将大大简化业务线的调用逻辑,存在的缺点是,如果缓存的数据业务逻辑比较复杂,async-update异步更新的逻辑可能也会比较复杂。
五、其他未尽事宜
本文只讨论了缓存架构设计中需要注意的几个细节点,如果数据库架构采用了一主多从,读写分离的架构,在特殊时序下,还很可能引发数据库与缓存的不一致,这个不一致如何优化,后续的文章再讨论吧。
六、结论强调
(1)淘汰缓存是一种通用的缓存处理方式
(2)先淘汰缓存,再写数据库的时序是毋庸置疑的
(3)服务化是向业务方屏蔽底层数据库与缓存复杂性的一种通用方式
http://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=404087915&idx=1&sn=075664193f334874a3fc87fd4f712ebc&scene=21#wechat_redirect
- 大小: 4 KB
- 大小: 6.6 KB
- 大小: 6.8 KB
- 大小: 8.4 KB
- 大小: 12.3 KB
分享到:
相关推荐
### Rails缓存架构设计 #### 一、高性能Web应用与缓存架构的重要意义 在现代互联网环境下,构建高性能Web应用面临着前所未有的挑战。随着用户数量的激增和技术的发展,Web应用不仅需要处理大规模且高并发的访问...
通过上述内容,我们能够了解到分布式缓存系统设计与实现的基本方法,以及Go语言在其中所扮演的角色和优势。当然,由于篇幅限制,无法详细展开每个章节的内容,但可以肯定的是,分布式缓存的原理和Go语言实现是一门...
系统架构设计师不仅需要深入理解上述技术细节,还要具备文档编写能力,能与系统分析师、项目管理师有效沟通。他们需要在满足功能需求的同时,考虑到系统的扩展性、安全性、可靠性和性能等因素,设计出适应业务发展...
虽然描述部分为空,但通过部分展示的内容,我们可以推断出这是一份深入探讨Web架构设计的资料,包含了丰富的技术细节和实践经验。 ### Web架构设计的关键概念 #### 不过度设计(Never Overdesign) 在Web架构设计...
系统架构设计师是一个至关重要的角色,他们负责设计和规划软件系统的整体结构,确保系统的高效、可扩展性和稳定性。这个角色不仅需要深入理解技术细节,还要具备良好的业务理解和沟通能力,以便为企业的信息技术需求...
Java后端架构设计精讲-大厂三面架构问题so-easy.docx 本资源是关于Java后端架构设计的面试宝典,主要面向中高级后端研发和想提前掌握架构设计知识的初级研发。该资源整合了架构设计面试中的六个方面,包括中间件、...
#### 二、高质量架构设计的概念 **高质量架构设计**是指在满足功能性需求的基础上,通过一系列的设计原则和技术手段来构建出具有高可靠性、高性能、易于维护和扩展的软件系统。这样的设计不仅能提高软件的质量,还...
在IT行业中,架构设计...以上内容基于对温昱"架构设计方法经验谈"的合理推测,具体细节和深度分析将需要查看PDF文档以获取完整信息。这份文档对于任何希望提升架构设计技能的IT从业者来说,无疑是一份宝贵的学习资料。
《软件架构设计说明书模板》是指导软件开发过程中的重要文档,它详细地描述了软件系统的架构,涵盖了系统各个方面的设计细节。以下将针对标题、描述和部分内容,详细阐述该模板的关键知识点。 1. **简介** - **...
#### 五、App架构设计思路 - **软件架构描述**:明确构成系统的各个抽象模块及其之间的通信方式。 - **模块细化**:在开发阶段,将抽象模块细化为具体的实现,如类或对象。 - **接口实现**:通过接口或协议代理的...
《架构风格与基于网络的软件架构设计》是Roy Thomas Fielding博士的一篇经典论文,它在IT领域,尤其是Web服务和API设计中具有深远影响。这篇论文详细阐述了Representational State Transfer (REST)架构风格,这是...
#### 二、架构设计的核心要素 ##### 1. 高并发处理能力 微信红包在春节等高峰期面临巨大的并发压力,如何有效处理这些高并发请求成为了设计中的关键问题。这不仅涉及到服务器的负载均衡、数据存储策略等方面的技术...
【架构PPT】是IT行业中一个重要的学习资源,通常用于分享和探讨软件系统的设计与组织。...同时,文档【架构和业务.docx】提供了更深入的细节和具体实例,有助于读者深入理解架构设计与业务之间的紧密联系。
#### 二、项目架构设计细节 在本节中,我们将详细介绍每个层次的具体实现方法。 ##### 2.1 表现层设计 - **使用MVP或MVVM模式**:MVP(Model-View-Presenter)和MVVM(Model-View-ViewModel)是两种常用的UI架构...
根据提供的文件信息,我们可以深入探讨系统架构师培训之应用架构设计的相关知识点,这些知识点主要集中在企业应用架构的基础、不同层次的设计、以及特定的设计方法和技术上。 ### 一、企业应用架构基础 #### 1. ...