缓存,已经是一个老生常谈的技术了,在高并发读的情况下对于读服务来说可谓是抗流量的银弹。

高并发三大利器:缓存、限流、降级。

今天我们就来谈谈缓存。对于缓存,我的理解是让数据更接近于用户,目的是让用户的访问速度更快。 所以距离越接近用户的缓存,越快越有效!缓存的工作原理是先从缓存中获取数据,如果有数据则直接返回给用户,如果没有数据则从慢速设备上读取实际数据并且将数据放入缓存。

按照层级关系,我们来划分一下缓存,同时也是我们今天的大纲:

浏览器缓存
浏览器是我们网上冲浪的重要工具,为了能够让我们顺畅的冲浪,它也会帮助我们缓存一些东西,主要存放一些实时性不太敏感的数据,比如商品详情页框架、商家评分、评价、广告词等。对于实时性要求高的数据则不能使用浏览器缓存。浏览器缓存是有过期时间的,我们可以通过对响应头Expires、Cache-control进行控制。

客户端缓存
客户端缓存很容易理解,意思就是存放在客户端的缓存。它的使用场景不多,在我们大促的时候,为了防止瞬间流量把服务端击垮,一般会在大促来临之前把app需要访问的一些素材(如js/css/image等)提前下发到客户端进行缓存,在大促来临之际app就不需要去拉取这些素材了。另外的话还有一些兜底数据或者样式文件也会存放于客户端缓存中,在服务端异常或者网络异常的时候保证app不崩。

CDN缓存
CDN(Content Delivery Network),即内容分发网络。它是建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的分布式网络。我们通常会将一些静态页面数据、活动页面、图片等数据存放于CDN缓存中。

CDN缓存有两种机制:推送机制(当内容变更后主动将数据推送到CDN节点)和拉取机制(先访问CDN节点,无数据的时候会从源服务器获取数据返回并存储CDN节点)

举个例子,如果你要去买汽车,你应该是到4s店去买汽车,如果4s店有你可以直接提走,如果4s店没有,那么4s店铺需要去进一批货,然后回到店铺,然后再给你。在这个case中,4s店其实就承当了一个CDN缓存节点的角色。

反向代理缓存
反向代理,我们一般情况都是指反向代理服务器Nginx。

Nginx缓存主要分为Nginx Http缓存与Nginx代理层缓存。

Nginx Http缓存提供expires、etag、if-modified-since指令来实现反向代理缓存。Nginx代理层缓存主要以Http模块与proxy_cacahe模块进行配置即可。

本地缓存
本地缓存,一般是指将客户机本地的物理内存划分出一部分空间用来缓冲客户机回写到服务器的数据。从全局的角度,我们可以有磁盘缓存、CPU缓存、应用缓存。

磁盘缓存分为读缓存和写缓存。

读缓存是指,操作系统为已读取的文件数据,在内存较空闲的情况下留在内存空间中(这个内存空间被称之为“内存池”),当下次软件或用户再次读取同一文件时就不必重新从磁盘上读取,从而提高速度。

写缓存实际上就是将要写入磁盘的数据先保存于系统为写缓存分配的内存空间中,当保存到内存池中的数据达到一个程度时,便将数据保存到硬盘中。

CPU缓存可以分为一级缓存(L1 Cache)、二级三级缓存(L2/L3)。当CPU要读取一个数据时,首先从L1中查找,没有的话再从L2/L3中查找,如果还没有那就从内存中查找,内存如果还没有那就从磁盘查找。查找顺序为:CPU->L1->L2/L3->内存->磁盘。

应用缓存分为本地应用缓存与其他应用缓存。

本地应用缓存指的是本服务所使用的缓存,用Java服务来举例,又分为 堆内缓存 与 堆外缓存 。

堆内缓存,一般指的是Java堆的缓存对象,堆内缓存的好处是不需要序列化/反序列化,也是最快的缓存,缺点也很明显,缓存数据多的时候,GC(垃圾回收)的频率会增大,时间会加长。堆内缓存一般使用软引用/弱引用来引用对象,使用这两种引用的好处是当堆内存不足时,可以强制回收这部分内存,释放堆空间。堆内缓存最大的问题是重启时内存中的缓存数据会丢失,如果堆内缓存使用的多,再加上刚好流量风暴,有可能击垮应用。堆内缓存的实现一般有:Guava Cache、Ehcache等。

堆外缓存,这个听说的同学比较少,它处于Java堆之外的内存,不受GC控制,也不受限堆大小,只受限于机器内存,所以,使用它一定小心谨慎,如果处理不当它可能存在内存泄漏的风险!堆外内存需要序列化/反序列化,所以它会比堆内缓存慢一些。

其他应用缓存,指的是除了本服务之外的缓存,比如local redis cache。local redis cache指的是在本服务器上部署一组Redis,应用直接读本机获取缓存数据,多机之间利用主从机制同步数据。这种方式的优点是没有网络消耗,性能是最优的。

分布式缓存
如果数据量不大的情况下,使用local redis cache的架构是最优的。

使用local redis cache最大的问题是

单机器容量问题
多实例数据一致性问题
多实例缓存命中率降低导致回源DB
如果遇到这样的问题,那么应该将数据分片,尽可能的均匀分布到多台服务器,这便是分布式缓存。

分布式缓存常见的分片策略有:

节点取余
一致性哈希
虚拟槽分区
我们最常见的Redis-Cluster集群则是使用虚拟槽分区的方式来对数据分片的。

我们点到即止,对于Redis缓存相关,后面会有很多文章来专门讨论,敬请期待吧。

其他:缓存命中率
缓存命中率是我们非常重要的一个指标,我们如果使用缓存,一定需要通过监控这个指标来看缓存的工作状态。

它的计算方式为:

命中率=缓存命中次数/读取总次数命中率 = 缓存命中次数/读取总次数命中率=缓存命中次数/读取总次数

缓存命中率越高越好,如何提高缓存命中率呢?我们应该对于不同场景数据有不同的缓存策略,比如:

大促来临之际应该提前将热点数据缓存,这种方式我们称之为缓存预热或缓存热加载;
在case1的基础上,将热点缓存数据与普通缓存数据做数据隔离,这一点前期需要人为干预,后期需要实时热点发现;
将数据分类,不同类别的数据配置合适的失效时间;
调整缓存粒度,通常情况下缓存粒度越小缓存命中率越高;
增大存储容量,当容量不够的时候会触发过期策略导致部分缓存数据失效,从而影响缓存命中率;
缓存问题:缓存击穿
缓存击穿是指数据库和缓存都没有的数据,每次都要经过缓存去访问数据库,大量的请求有可能导致DB宕机。(强调都没有数据+并发访问)

缓存问题:缓存穿透
缓存击穿是指数据库有,缓存没有的数据,大量请求访问这个缓存不存在的数据,最后请求打到DB可能导致DB宕机。(强调单个Key过期+并发访问)

缓存问题:缓存雪崩
缓存击穿是指数据库有,缓存没有的数据,大量请求访问这些缓存不存在的数据,最后请求打到DB可能导致DB宕机。(强调批量Key过期+并发访问)

缓存问题:缓存一致性
缓存一致性指的是缓存与DB之间的数据一致性,我们需要通过各种手段来防止缓存与DB不一致,我们要保证缓存与DB的数据一致或者数据最终一致。

缓存的其他问题
缓存的好处我们非常受益,用户的每一次请求都伴随着无数缓存的诞生,但是缓存同时也给我们带来了不小的挑战,比如在上面提到的一些疑难课题:缓存穿透、缓存击穿、缓存雪崩和缓存一致性。

除此之外,我们还会涉及到其他的一些缓存难题,如:缓存倾斜、缓存阻塞、缓存慢查询、缓存主从一致性问题、缓存高可用、缓存故障发现与故障恢复、集群扩容收缩、大Key热Key…

最后
如果你觉得此文对你有一丁点帮助,点个赞。或者可以加入我的开发交流群:1025263163相互学习,我们会有专业的技术答疑解惑

如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点star:http://github.crmeb.net/u/defu不胜感激 !

PHP学习手册:https://doc.crmeb.com
技术交流论坛:https://q.crmeb.com

深入浅出分布式系统中的缓存架构相关推荐

  1. 理解分布式系统中的缓存架构(下)

    承接上一篇<理解分布式系统中的缓存架构(上)>,介绍了大型分布式系统中缓存的相关理论,常见的缓存组件以及应用场景,本文主要介绍缓存架构设计常见问题以及解决方案,业界案例. 1. 分层缓存架 ...

  2. 理解分布式系统中的缓存架构(上)

    本文主要介绍大型分布式系统中缓存的相关理论,常见的缓存组件以及应用场景. 1. 缓存概述 缓存概述 2. 缓存的分类 缓存主要分为以下四类 缓存的分类 2.1 CDN缓存 基本介绍 CDN(Conte ...

  3. 深入理解分布式系统中的缓存架构(下)

    转载自   深入理解分布式系统中的缓存架构(下) 承接上一篇<理解分布式系统中的缓存架构(上)>,介绍了大型分布式系统中缓存的相关理论,常见的缓存组件以及应用场景,本文主要介绍缓存架构设计 ...

  4. 深入理解分布式系统中的缓存架构(上)

    转载自   深入理解分布式系统中的缓存架构(上) 本文主要介绍大型分布式系统中缓存的相关理论,常见的缓存组件以及应用场景. 1 缓存概述 2 缓存的分类 缓存主要分为以下四类 2.1 CDN缓存 基本 ...

  5. 大型分布式系统中的缓存架构

    作者:陈彩华 来自:51cto技术栈(ID:blog51cto) 本文主要介绍大型分布式系统中缓存的相关理论,常见的缓存组件以及应用场景. 缓存概述 缓存概述 缓存的分类 缓存主要分为四类,如下图: ...

  6. 快速掌握:大型分布式系统中的缓存架构

    关注我们获得更多内容 " 本文主要介绍大型分布式系统中缓存的相关理论,常见的缓存组件以及应用场景. 缓存概述 缓存概述 缓存的分类 缓存主要分为四类,如下图: 缓存的分类 CDN 缓存 CD ...

  7. 深入理解分布式技术 - 分布式系统中的缓存

    文章目录 缓存无处不在 缓存的分类 前端缓存 网络传输缓存 服务端缓存 数据库缓存 缓存无处不在 缓存是分布式系统开发中的常见技术,在分布式系统中的缓存,不止 Redis.Memcached 等后端存 ...

  8. 高并发高可用复杂系统中的缓存架构(十六) 实现缓存与数据库双写一致性保障方案

    再来回顾下之前的思路: 数据更新:根据唯一标识路由到一个队里中,「删除缓存 + 更新数据」 数据读取:如果不在缓存中,根据唯一标识路由到一个队里中,「读取数据 + 写入缓存」 投入队里之后,就等待结果 ...

  9. 大型网站架构系列:缓存在分布式系统中的应用(一)

    缓存是分布式系统中的重要组件,主要解决高并发,大数据场景下,热点数据访问的性能问题.提供高性能的数据快速访问. 本文是缓存在分布式应用第一篇文章,介绍缓存的原理,缓存的分类,缓存的设计,CDN缓存(原 ...

最新文章

  1. Linux下挂载存储设备
  2. javascript添加HTML事件处理程序的两种方式学习
  3. Mysql无法添加环境变量解决办法
  4. 页面头部title、description、keywords标签的优化
  5. linux安装.AppImage后缀安装包
  6. 【tf.keras】tf.keras模型复现
  7. 每日一道剑指offer-两个栈来实现一个队列
  8. kettle简单的更新与插入
  9. PTA-查询水果价格
  10. 有什么方法可以免费查重呢?
  11. 软件测试常见的问题概略
  12. 开启ICT宝藏之门——CloudOpera IES 创新社区正式成立
  13. 《大江大河2》里的创业故事
  14. .net mvc 利用分部视图局部刷新.
  15. 通过Fiddler实现部分静态资源代理
  16. cmd package install-create -r -t -S returns error
  17. ThinkSNS安装手记
  18. SAP SuccessFactors 功能介绍
  19. js版微信测试号推送消息、生日、纪念日、网易云热评、舔狗日记【JavaScript版】保姆级教程 青龙面板做微信测试号推送生日、纪念日
  20. 我们该如何看待AI的崛起

热门文章

  1. 软件工程第三周作业:微软必应词典案例分析
  2. 韩国商业网站设计分析
  3. android手机执行linux命令 如telnet ifconfig ping
  4. 外网上传到NAS速度很慢是什么情况?上行1M都不到,但是测试有4M
  5. 《阴阳师·1琵琶之宝玄象为鬼所窃》原作:梦枕貘
  6. 《统计学习方法》第一章总结
  7. Python数据库及ORM框架对比选择
  8. chrome插件获取页面html,chrome扩展实现获取网页数据的功能
  9. 学习笔记21.08.16:利用python的cplex库解决混合整数规划MIP问题
  10. 一款轻松免杀主流杀软的c2框架