高速输出-咱们戏说缓存

前言

缓存要解决的问题是速度的问题,使用缓存的目的是为了减小对物理资源的访问,缓存大量的应用在软硬件的方方面面,从 CPU 到硬盘,就应用了 一级缓存、二级缓存,少部分高速缓存和大量低速缓存相结合,以提升 CPU 的计算能力,本文讲的主要是系统集成项目中的软件级别的缓存。sql

缓存因果图

缓存在现代系统中的位置能够说是举足轻重,不是无关紧要的问题了,而是怎么样用好的问题。怎么样讲好缓存这个话题,我思考了好久;若是是生搬硬套,我估计我确定是凉凉,但要是上来就一顿代码操做,显得字太多,各位看官老爷也是要喷死个人(大家喷我算我赢)。各位看官就当故事随便看看就行了。数据库

客户端缓存

小明同窗是一个大学生,每月都会从爸爸那里领取生活费,因为爸爸给的生活费比较充裕,他就将一部分存了起来,周而复始,固定频率,这就是浏览器网页缓存;有一天,他接到爸爸的一个电话,说每月给现金,我老是从银行拿也不方便,这样,咱给存银行卡里头,可是说好了,每月1号的时候转1000块进去,3号以前能够领取,过期不侯。这就是 Cookie!小明说爸,这时间太紧迫了,我万一太过于专心学习忘记取钱那你儿子但是要饿死的吖,到时候没人给你养老送终事儿就大了。他爸爸通过深思熟虑后,决定放开取现时间的限制:行,你想何时取都成,就是别把卡给弄掉了就行。这就是LocalStorage/IndexDB,浏览器本地存储。若是银行卡掉了(浏览器重装,删库跑路),那还得找爸爸。浏览器

服务器缓存

咱们本次讨论的重点就是服务器缓存,对于小明的爸爸来讲,每次给小明生活费以前都要到银行(数据库)去取钱出来,实在是太麻烦,不如提早把钱取出来准备好,每次取半年的钱出来放家里保险箱里(缓存),小明申请生活费的时候,直接给他就行了,节约时间效率又高,惟一的问题就是可能没那么安全,有可能被小偷把钱给偷了(缓存更新),而后就是半年时间事后再从新取一笔出来(缓存过时策略)。缓存

静态对象缓存

静态对象也是一种特殊的缓存,静态对象做用于程序的整个生命周期中。须要注意的是,静态对象不会被 GC 回收 ,可是,若是静态对象被屡次引用覆盖,那么以前的引用就有可能被 GC 回收。这就好像,小明在向爸爸领取生活费的时候,发现此次领到手的钱实在是太破旧了,都很差意思花出去,爸爸只好从新给了另外一份。安全

会话级缓存

在 Web 站点中,Session 是私有制的,各个 Session 之间是不会共享内存对象的,咱们能够利用这个特性(在Asp.NET 时代经常使用)来暂时保存一些数据,例如用户购物车。仍是以小明的需求为例子,小明下面还有一个妹妹,妹妹每月均可以从爸爸那里多领取200元生活费,看到妹妹的资源这么好,小明愤愤不平,就像妹妹提议共享生活费,一家人一块儿用,多好吖!结果小明被爸爸揍了一顿,还收回了部分生活费。服务器

进程级别缓存

基本上每一个应用程序都具备本地缓存的能力,在 Asp.NET 中就有 MemoryCache ,也叫作进程级缓存(本地缓存),MemoryCache 和 分布式缓存的做用基本一致,所不一样的是,本地缓存在应用程序中止后就会被释放掉,没法进行持久存储。就好像,小明在上大学期间,每月都是生活费的,可是到暑假的时候就没有了(只能靠苦逼的暑期工挣点生活费啊)。运维

分布式缓存

分布式缓存是个好东西,目前市场上出现了很是多的 nosql 数据库,均可用做缓存数据库,有时候,这些缓存数据库也提供持久化的能力。nosql

小明家的生活条件,在通过爸爸的不懈努力以后,生活水平渐渐提升了;有一天,爸爸对小明说:明仔吖,我们家如今生活水平提升了,可是爸爸也愈来愈忙了,这样,若是我忙的时候,你问妈妈或者爷爷奶奶,也是能够拿到生活费的,我们家这几位长辈手里都有钱了,这就是分布式缓存。分布式

可是分布式缓存又分为主从模式和集群模式,上面说的是集群模式,爸爸妈妈爷爷奶奶均可以拿钱,可是主从模式就不一样了,主从模式就是钱都在爸爸手里,爸爸会把钱分给每一个长辈一份,若是当时正好爸爸太忙了,没来得及分给妈妈,而小明又刚好问妈妈要生活费的话;妈妈只能对他说:小命呀,很差意思,妈妈这里也没有,你看看再问问其它人(客户端本身轮询),在问了妈妈、爷爷后(引用指向),终于知道,钱在爸爸那里,还得问爸爸要生活费。并且爸爸给其它人分钱的时候,还要占用他工做的时间。工具

缓存雪崩

缓存雪崩就是在某一个时刻,大量的缓存同时失效,形成数据库访问压力倍增。小明的爸爸最近压力比较大,由于收入减小了,他爸爸作的一个工程由于种种缘由,货款只能分期付清,为了防止小明和妹妹同时申请生活费,形成资金周转困难;爸爸规定妹妹 1 号领取生活费,而小明在 5 号才能领取,小明内心的苦啊!

缓存穿透

缓存穿透就是客户端老是尝试访问某个不存在的缓存,形成了每次都要取请求数据库读取数据。就好像小明吧,原本生活挺平静的,这刚上大二,就交了个女友,每月的 1000 元生活费有点捉襟见肘,而后他又不能让爸爸知道,就在申请生活费的时候,每次都多要一点;这样就搞得爸爸很被动,原本计划得好好的,每月都是 1000 块,这没次都不够,总是要跑银行取现金,终于在3个月后,爸爸发现了这个问题,想着儿子也大了,为了早日抱上孙子,就提升了小明的生活费,解决了每次都要跑银行的问题。

缓存击穿

缓存击穿和缓存雪崩有点相似,其中不一样的是;缓存雪崩是大量缓存 key 同时过时,而缓存击穿是大量的请求指向同一个缓存key,在这个 key 过时的时候,大量的请求涌入数据库中,形成了瞬间巨大的压力。举个栗子,由于小明交了女友的缘由,他的生活费老是很快用完了;这种状况下,他也必须在 1 号的时候拿到生活费,否则就要吃土了,可是妈妈不容许他们一块儿取打扰爸爸,妈妈就指定了妹妹去问,在妹妹没有回来以前,小明只能等着,这就是为了解决缓存击穿而采用的策略:互斥锁(mutex key)

运维级别缓存

除了在应用程序中能够接入缓存之外,部分运维工具也集成了缓存服务,好比 Nginx、IIS。

代理缓存

Nginx 就是反向代理缓存,经过配置 Nginx 的缓存功能,在客户端请求到来到时候去加载缓存内容,用以提升响应能力,IIS 缓存又分为用户缓存和内核缓存。IIS 的输出缓存设置中,内核模式缓存不会对验证等用户信息进行检查,就好像小明等爸爸由于太赶时间,把钱放门卫大妈那里了,结果随便来了个学生就把小明等生活费给领走了,可是加上用户模式缓存后,就能够添加对身份的检查(请求标头),这样大妈就会知道谁是小明而不会随便把生活费交给别人了。

网页静态化

这种技术,在 Web1.0 时代很是的流行,我还记得那些个年头的网站开发项目中的要求,大部分项目的需求分析文档里面就明晃晃的写着:网页静态化!,而静态化常见于各类企业型、论坛帖子,在发表这些信息后就将其生成静态网页,客户端访问的时候,直接重定向到该静态网页,基本无需访问数据库。

CDN 缓存

CDN 缓存相似于上面提到的分布式缓存,可是实际上 CDN 缓存服务目前来讲,主要说针对静态资源的,好比图片、视频、文件等等;你们常常能够看到,不少站点都号称提供了 CDN 加速服务,这些站点就像一个个代办信用卡的销售中介,实际上拿的都是银行的资源。

更形象一些的说法,就是你们的钱都是中国人民银行发行的,咱们能够经过各个不一样的银行(CDN节点)查询咱们的银行卡余额(我怎么可能有余额),在之前没有手机银行的时候,你们就能够到附近的银行去查询,而后取款(CDN缓存),若是附近的银行的柜员机没有现金,那么可能就须要到总行去取了(回源),若是发生了太多回源的事件,就会形成 CDN 的拥堵,因此 CDN 服务商也不敢打包票本身的基础服务没有问题,反正我是没见到哪家 CDN 服务商敢注明服务稳定性 100%,基本上都是 99.99%

结束语

缓存的理论知识,实际上是很是宏大的,我这里只是抛砖引玉,但愿能给入门的朋友带来一点帮助,若是你喜欢这篇文章,请给我点赞,让更多同窗能够看到。

相关文章
相关标签/搜索