`
booboofd
  • 浏览: 555 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

缓存架构设计细节二三事

 
阅读更多
本文主要讨论这么几个问题:

(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缓存架构设计

    ### Rails缓存架构设计 #### 一、高性能Web应用与缓存架构的重要意义 在现代互联网环境下,构建高性能Web应用面临着前所未有的挑战。随着用户数量的激增和技术的发展,Web应用不仅需要处理大规模且高并发的访问...

    分布式缓存 原理 架构及Go语言实现-高清-完整目录

    通过上述内容,我们能够了解到分布式缓存系统设计与实现的基本方法,以及Go语言在其中所扮演的角色和优势。当然,由于篇幅限制,无法详细展开每个章节的内容,但可以肯定的是,分布式缓存的原理和Go语言实现是一门...

    web架构设计经验分享.pdf

    虽然描述部分为空,但通过部分展示的内容,我们可以推断出这是一份深入探讨Web架构设计的资料,包含了丰富的技术细节和实践经验。 ### Web架构设计的关键概念 #### 不过度设计(Never Overdesign) 在Web架构设计...

    系统架构设计师(教程学习资料)

    系统架构设计师是一个至关重要的角色,他们负责设计和规划软件系统的整体结构,确保系统的高效、可扩展性和稳定性。这个角色不仅需要深入理解技术细节,还要具备良好的业务理解和沟通能力,以便为企业的信息技术需求...

    Java后端架构设计精讲-大厂三面架构问题so-easy.docx

    Java后端架构设计精讲-大厂三面架构问题so-easy.docx 本资源是关于Java后端架构设计的面试宝典,主要面向中高级后端研发和想提前掌握架构设计知识的初级研发。该资源整合了架构设计面试中的六个方面,包括中间件、...

    高质量架构设计

    #### 二、高质量架构设计的概念 **高质量架构设计**是指在满足功能性需求的基础上,通过一系列的设计原则和技术手段来构建出具有高可靠性、高性能、易于维护和扩展的软件系统。这样的设计不仅能提高软件的质量,还...

    温昱---架构设计方法经验谈

    在IT行业中,架构设计...以上内容基于对温昱"架构设计方法经验谈"的合理推测,具体细节和深度分析将需要查看PDF文档以获取完整信息。这份文档对于任何希望提升架构设计技能的IT从业者来说,无疑是一份宝贵的学习资料。

    软件架构设计说明书模板

    《软件架构设计说明书模板》是指导软件开发过程中的重要文档,它详细地描述了软件系统的架构,涵盖了系统各个方面的设计细节。以下将针对标题、描述和部分内容,详细阐述该模板的关键知识点。 1. **简介** - **...

    ios架构与设计

    #### 五、App架构设计思路 - **软件架构描述**:明确构成系统的各个抽象模块及其之间的通信方式。 - **模块细化**:在开发阶段,将抽象模块细化为具体的实现,如类或对象。 - **接口实现**:通过接口或协议代理的...

    架构风格与基于网络的软件架构设计 中英版

    《架构风格与基于网络的软件架构设计》是Roy Thomas Fielding博士的一篇经典论文,它在IT领域,尤其是Web服务和API设计中具有深远影响。这篇论文详细阐述了Representational State Transfer (REST)架构风格,这是...

    微信红包的架构设计简介

    #### 二、架构设计的核心要素 ##### 1. 高并发处理能力 微信红包在春节等高峰期面临巨大的并发压力,如何有效处理这些高并发请求成为了设计中的关键问题。这不仅涉及到服务器的负载均衡、数据存储策略等方面的技术...

    架构PPT架构PPT

    【架构PPT】是IT行业中一个重要的学习资源,通常用于分享和探讨软件系统的设计与组织。...同时,文档【架构和业务.docx】提供了更深入的细节和具体实例,有助于读者深入理解架构设计与业务之间的紧密联系。

    安卓app项目架构设计文档

    #### 二、项目架构设计细节 在本节中,我们将详细介绍每个层次的具体实现方法。 ##### 2.1 表现层设计 - **使用MVP或MVVM模式**:MVP(Model-View-Presenter)和MVVM(Model-View-ViewModel)是两种常用的UI架构...

    系统架构师培训之应用架构设计.pdf

    根据提供的文件信息,我们可以深入探讨系统架构师培训之应用架构设计的相关知识点,这些知识点主要集中在企业应用架构的基础、不同层次的设计、以及特定的设计方法和技术上。 ### 一、企业应用架构基础 #### 1. ...

    秒杀系统架构设计.pdf

    ### 秒杀系统架构设计知识点概述 #### 一、热点数据与...综上所述,秒杀系统架构设计不仅涉及到热点数据管理、流量控制等技术细节,还需要考虑整体架构的优化和演进策略,以确保在高并发环境下提供稳定高效的服务。

Global site tag (gtag.js) - Google Analytics