一、背景

对于传统的后端业务场景(或者单机应用)中,访问量以及对响应时间的要求均不高,通常只使用DB即可满足要求。这种架构简单,便于快速部署,很多网站发展初期均考虑使用这种架构。但是随着访问量的上升,以及对响应时间的要求提升,单DB无法再满足要求。这时候通常会考虑DB拆分(sharding)、读写分离、甚至硬件升级(SSD)等以满足新的业务需求。但是这种方式仍然会面临很多问题,主要体现在:

1、性能提升有限,很难达到数量级上的提升,尤其在互联网业务场景下,随着网站的发展,访问量经常会面临十倍、百倍的上涨。

2、成本高昂,为了承载N倍的访问量,通常需要挂载更多的只读库,或者升级数据库实例的规格。

在计算机科学领域中有一句话:任何问题都可以通过增加一个间接的中间层来解决。本次的分享正是介绍解决以上问题的一个中间层——缓存层设计。

二、前言

鉴于缓存层的设计异常的复杂,需要考虑的问题很多,诸如:更新策略,缓存穿透,缓存一致性,缓存并发,缓存雪崩等。

本次只涉及到缓存的更新策略部分。

三、缓存层鸟瞰图

如上图所示,为了解决数据库性能瓶颈问题,对于读多写少的数据查询,可以通过多架设一层缓存层来减少对DB的直接访问。由于一般缓存中间件(redis、memcached)的key-value对都是常驻内存的,所以如果能直接命中缓存,一来可以极大的提高网站的响应速度,二来也可以大幅地减少直接对数据库的操作。

缓存层的工作原理一般分为以下两步:

1ã  当应用发起查询请求时,可以先通过查询缓存中的数据,如果命中缓存结果即可马上响应请求。

2ã  如果没有命中缓存,或者缓存已经失效了,则需要直接查询数据库,再次将结果缓存起来,如果响应请求,返回数据。

四、缓存更新策略

有了以上基本了解,我们进入到本次分享的主题——缓存更新策略。

首先思考一下,为什么会有缓存更新策略的问题,这个策略需要解决的又是什么问题?

缓存层是解决数据库性能的一个中间层,既然是中间层,那么引入缓存层当然不能影响以前正常的业务操作。这里就引出了一个问题,就是如何确保缓存层中的数据与数据库中数据的一致性问题。缓存更新策略正是为了处理数据一致性的问题而诞生的。

缓存更新的模式有四种:Cache aside,Read through,Write through,Write behind caching。

1、 Cache aside(缓存预留)

这是最常用最常用的策略。其具体逻辑如下:

失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。

命中:应用程序从cache中取数据,取到后返回。

更新:先把数据存到数据库中,成功后,再让缓存失效。

2、Read/Write Through (直接读/写)

Read Through 就是在查询操作中更新缓存,也就是说,当缓存失效或过期的时候,Cache Aside是由调用方负责把数据加载入缓存,而Read Through则用缓存服务自己来加载,从而对应用方是透明的。

Write Through 和Read Through类似,不过是在更新数据时发生。当有数据更新的时候,如果没有命中缓存,直接更新数据库,然后返回。如果命中了缓存,则更新缓存,然后再由Cache自己更新数据库(这是一个同步操作)。

我们可以看到,在上面的Cache Aside中,我们的应用代码需要维护两个数据存储,一个是缓存(Cache) ,一个是数据库(Repository)。所以,应用程序比较难维护。而Read/Write Through是把更新数据库(Repository)的操作由缓存自己代理了,所以,对于应用层来说,就简单很多了。可以理解为,应用认为后端就是一个单一的存储,而存储自己维护自己的Cache。

/3、 Write Behind Caching(回写)

在更新数据的时候,只更新缓存,不更新数据库,而我们的缓存会异步地批量更新数据库。这个设计的好处就是让数据的I/O操作飞快无比(因为直接操作内存) ,因为异步,Write Behind Caching还可以合并对同一个数据的多次操作,所以性能的提高是相当可观的。

Write Behind Caching实现逻辑比较复杂,因为他需要追踪有哪数据是被更新了的,需要刷到持久层上。

但是,其带来的问题是,数据不是强一致性的,而且可能会丢失(Unix/Linux非正常关机会导致数据丢失,就是因为这个原因,因为Linux文件系统的Page Cache的算法使用的就是write back,类似于Write Behind Caching)。在软件设计上,我们基本上不可能做出一个没有缺陷的设计,就像算法设计中的时间换空间,空间换时间一个道理,有时候,强一致性和高性能,高可用和高性性是有冲突的。

äºã思考

思考如下场景:

1、用户A将商品S的售价从50修改为100

2、同一时间用户B在进行开单操作

这种情况下如何确保用户B在出售商品S的时候,售价是100呢?

使用上述的缓存更新策略,是否能解决这个场景问题。

还是不能的,比如,一个是读操作,但是没有命中缓存,然后就到数据库中取数据,此时来了一个写操作,写完数据库后,让缓存失效,然后,之前的那个读操作再把老的数据放进去,所以,会造成脏数据。

但,这个案例理论上会出现,不过,实际上出现的概率可能非常低,因为这个条件需要发生在读缓存时缓存失效,而且并发着有一个写操作。而实际上数据库的写操作会比读操作慢得多,而且还要锁表,而读操作必需在写操作前进入数据库操作,而又要晚于写操作更新缓存,所有的这些条件都具备的概率基本并不大。

所以,要么通过2PC或是Paxos协议保证一致性,要么就是拼命的降低并发时脏数据的概率,而Facebook使用了这个降低概率的这种方法,因为2PC太慢,而Paxos太复杂。当然,最好还是为缓存设置上过期时间。

缓存层设计套路(一)相关推荐

  1. Redis缓存策略设计及常见问题

    Redis缓存设计及常见问题 缓存能够有效地加速应用的读写速度,同时也可以降低后端负载,对日常应用的开发至关重要.下面会介绍缓存使用技巧和设计方案,包含如下内容:缓存的收益和成本分析.缓存更新策略的选 ...

  2. 搞懂分布式技术15:缓存更新的套路

    缓存更新的套路 看到好些人在写更新缓存数据代码时,先删除缓存,然后再更新数据库,而后续的操作会把数据再装载的缓存中.然而,这个是逻辑是错误的.试想,两个并发操作,一个是更新操作,另一个是查询操作,更新 ...

  3. 微服务的接入层设计与动静资源隔离

    作者:刘超,毕业于上海交通大学,15年云计算领域研发及架构经验,先后在EMC,CCTV证券资讯频道,HP,华为,网易从事云计算和大数据架构工作.在工作中积累了大量运营商系统,互联网金融系统,电商系统等 ...

  4. petshop详解之五:PetShop之业务逻辑层设计

    五 PetShop之业务逻辑层设计业务逻辑层(Business Logic Layer)无疑是系统架构中体现核心价值的部分.它的关注点主要集中在业务规则的制定.业务流程的实现等与业务需求有关的系统设计 ...

  5. 微服务化之缓存的设计

    此文已由作者刘超授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 在高并发场景下,需要通过缓存来减少数据库的压力,使得大量的访问进来能够命中缓存,只有少量的需要到数据库层.由于 ...

  6. 基于SSD的Kafka应用层缓存架构设计与实现

    Kafka在美团数据平台承担着统一的数据缓存和分发的角色,针对因PageCache互相污染,进而引发PageCache竞争导致实时作业被延迟作业影响的痛点,美团基于SSD自研了Kafka的应用层缓存架 ...

  7. petshop4.0 详解之五(PetShop之业务逻辑层设计)[转]

    业务逻辑层(Business Logic Layer)无疑是系统架构中体现核心价值的部分.它的关注点主要集中在业务规则的制定.业务流程的实现等与业务需求有关的系统设计,也即是说它是与系统所应对的领域( ...

  8. petshop4.0 详解之五(PetShop之业务逻辑层设计)

    五 PetShop之业务逻辑层设计 业务逻辑层(Business Logic Layer)无疑是系统架构中体现核心价值的部分.它的关注点主要集中在业务规则的制定.业务流程的实现等与业务需求有关的系统设 ...

  9. PetShop之业务逻辑层设计

    <解剖PetShop>系列之五 五 PetShop之业务逻辑层设计 业务逻辑层(Business Logic Layer)无疑是系统架构中体现核心价值的部分.它的关注点主要集中在业务规则的 ...

最新文章

  1. HDU 1257 - 最少拦截系统 ( LIS / 贪心 )
  2. iOS进阶之架构设计MVVM的理解(3)
  3. I don't have an E-mail 我没邮箱
  4. html页面刷新回到顶部_HTMl页面中返回顶部的几种实现小结
  5. 获取某个时间开始 之后的 N次[周几,周几]
  6. beego 快速入门
  7. 基于RBAC的设计思路
  8. PHP调用新浪API 生成短链接
  9. windows平台下基于QT和OpenCV搭建图像处理平台
  10. 《深入理解Java虚拟机》读书笔记3--垃圾回收算法
  11. amd cpu不能在cmd环境下运行java代码_「我们一起学Java02」JDK、JRE、JVM简介,Java开发平台的搭建...
  12. 21个深度学习调参的实用技巧
  13. pt100温度传感器c语言,pt100测温程序-LCD1602
  14. CentOS安装mysql*.rpm提示conflicts with file from package的解决的方法
  15. 论 BUG调试与(程序猿)初学者
  16. html向下的箭头符号,向下的箭头符号
  17. 帝国php忘记密码,帝国cms7.5忘记登录密码以及多次登录失败被锁定终极解决办法-更新...
  18. 「Nescafé26」 Freda的传呼机 【树上倍增+图论】
  19. 孵化中国网络安全未来,ISC 2021创新独角兽沙盒大赛开启招募
  20. 智点创科机器人_校园里来了个机器人——智点创科天才学院走进祥阁学校

热门文章

  1. zip2john工具爆破zip文件
  2. Python 编码问题:‘ascii‘ codec can‘t encode characters in position 的解决方案(中文乱码终极解决方案)
  3. 我经常访问的技术网站
  4. redmine测试使用小结
  5. 如何嗅闻交换网络和ARP骗子-ARP解释的原则
  6. BZOJ2081 [Poi2010]Beads
  7. GConf error:Failed to contact configuration server
  8. PHP实现http与https转化
  9. 过去的2018年,400000粉丝用指尖投票,选出了这10本技术书
  10. 为什么你跟高手有差距?因为他们会在假期里读这5本书