缓存就会用!它架构还没听过?分布式多级缓存架构知识大瓶装,25 张图打包拎走

一谈缓存,内心顿时豁然开朗。迫于key-value的形式,总感觉轻风扶面,杨柳依依,一切都尽在我掌握之中。犹如那一眼相中佳人的冲动,脑子里尽是佳人的容颜。

用来存放当前访问最频繁的少数活动页面的页数。当某用户需存取数据时,根据数据所在的逻辑页 在块表中找到对应的内存块 ,再联系其页内地址,形成物理地址。

总结:读取数据时–>先找逻辑页—>排查内存块 —>获得物理层内存表示页内地址—->物理地址

如果块表中没有相应的逻辑页 ,则地址映射仍然可以通过内存中的页表进行操作,只是它得到是空闲块 ,必须将该块 填入块表中的空闲区。如果块表中没有空闲区,则根据淘汰算法淘汰块表中的某一行,在填入新的页 和块 。

我记得计算机获取缓存是按照就近原则的,那它们的优先级呢/p>

缓存会根据存储速度来选择最合适的存储器,离CPU越近的存储器,速度越快,每字节的成本越高,同时容量也因此越小

分层如下:寄存器(离CPU最近,寄存器速度最快)、高速缓存(缓存也是分级,有L1,L2等缓存)、主存(普通内存)、本地磁盘

为什么使用多级缓存架构/strong>

根本在于为 站提供高性能服务,让用户具有更好的用户体验。以较少的成本获取更大的性能空间。

聊聊用户体验

用户体验这个词最早被广泛认知是在20世纪90年代中期,由用户体验设计师唐纳德·诺曼(Donald Norman)提出和推广。

因信息技术在移动和图像处理等方面取得的进展已经使得人机交互(HCI)技术几乎渗透到人类活动的所有领域。这导致系统的评价指标从单纯的可用性,扩展到用户体验。

用户体验在人机交互技术发展过程中受到了相当的重视,其关注度与 传统的三大可用性指标(即效率、效益和基本主观满意度不相上下,甚至在某些方面更为重要。

什么是用户体验/strong>

ISO 9241-210 标准将用户体验定义为 “人们对正在使用或期望使用的产品、系统或者服务的认知印象和回应” 。因此,用户体验是主观的,且注重实际应用。

用户体验:即用户在使用一个产品或系统之前、使用期间和使用之后的全部感受,包括情感、信仰、喜好、认知印象、生理反应、心理反应、行为和成就等各个方面。

ISO标准也暗示了可用性也可以作为用户体验的一个方面,“可用性标准可以用来评估用户体验的一些方面”。不过,该ISO标准并没有进一步阐述用户体验和系统可用性之间的具体关系。显然,这两者是相互重叠的概念。

也许这就是产品不断折腾咱技术的原因,多少得懂点。不知你家产品如何无da人的冲动

还可以把进一步分解为 络传输时间和“应用延迟时间”

  • 络传输时间:数据在客户端和服务器端进行传输的时间
  • 应用延迟时间:系统实际处理请求业务所需时间

以后谈优化,那就应该从整个请求链路里着手,针对呈现、 络传输、应用处理时间

吞吐量

吞吐量 是指系统在单位时间内处理请求的数量。

单位时间是项目自身规划响应时间来进行描述的,但常用 1s 来衡量处理成功的请求量。

那我 站的吞吐量怎么计算呢为小吒的我,还是补了课的
要计算吞吐量首先要看你的时间换算和流量情况。

  • 单位时间划分
    假设一个发布系统的广告页要满足30分钟内总访问量为500w。
    那平均QPS为:500w/(30*60) = 2778,大概3000 QPS /S(要预留空间)
  • 按天算
    假设某个信息分类 站首页日均PV约8000w
    那平均QPS为:一天按照4W秒算(晚上不计算),8000w/4w= 2000,大概2000QPS。

注:
用户不会全天都使用软件,一般晚上不会使用或者使用人很少。但也分业务,你像直播、外卖等。但一天12小时基本上满足一个用户当天最大使用软件的时间。

具体用户在线使用APP的时间也不确定,具体应该根据自身项目统计用户的使用时间和总流量来计算平均QPS。利用高峰期流量来计算最大QPS。

对于无并发的应用系统而言,吞吐量与响应时间成严格的反比关系,实际上此时吞吐量就是响应时间的倒数。

因此,缓存是系统调优时常用且行之有效的手段,无论是操作系统还是应用系统,缓存策略无处不在。“缓存为王”本质上是系统性能为王,对用户而言就是用户体验为王。

站架构缓存演进

起步

最初的 站可能就是一台物理主机,放在IDC或者租用的是云服务器,上面只运行着 应用服务器和数据库,LAMP(Linux Apache MySQL PHP)就是这样流行起来的。

中期

随着访问 站的人数越来越多,响应速度又开始变慢了,可能是 访问数据库的操作太多,导致数据连接竞争激烈,因此缓存开始登场。

这里不难看出,数据库往往是考虑优化的首选,毕竟没缓存请求直连数据库,而数据库又是数据的集中地,查数据还会涉及磁盘I/O。压力可想而知

若想通过缓存机制来减少数据库连接资源的竞争和对数据库读的压力,那么可如下选择:

  • 静态页面缓存: 这样程序上可以不做修改,就能够很好地减少对Web服务器的压力以及减少对数据库连接资源的竞争。
  • 动态缓存: 将动态页面里相对静态的部分也缓存起来,因此考虑采用类似的页面片段缓存策略(通过nginx、Apache配置实现动态缓存)

静态缓存更倾向于静态资源的缓存和浏览器的缓存。动态缓存是通过页面访问后,在编译生成缓存文件,提供给后续请求访问。有点像模板引擎

开始数据库调优,优化数据库自身的缓存,接下来是采用数据库集群以及分库分表的策略

分库分表的规则是有些复杂的,考虑增加一个通用的框架来实现分库分表的数据访问,这个就是数据访问层(Data Access Layer,DAL)。

  • 缓存同步机制:每台web服务器,都会是保存一份缓存文件,那数据之间就需要缓存的同步机制来完成。
  • 共享存储:共享存储是指两个或多个处理机共用一个主存储器的并行体系结构,像Redis。
  • 共享文件系统:两台机器之间的文件系统能够更加紧密地结合在一起,让一台主机上的用户可以像使用本机的文件系统一样使用远程机的文件系统。像Samba和NFS。

后期

该阶段可能会发现之前的缓存同步方案会出现问题,因为数据量太大,导致现在不太可能将缓存存储在本地后再同步,这样会造成同步的时间延迟从而增大响应时间、数据不一致性,数据库耦合缓存。
于是分布式缓存终于来了,将大量的数据缓存转移到分布式缓存上。

如果使用共享文件系统或共享存储有啥问题/p>

  • 共享存储:多个服务访问一个存储,那么容易造成单例性能不足的问题和。如果是并发读写可能会导致缓存和数据不一致问题。
  • 共享文件:多个服务压力太大,因文件I/O开销大。性能会导致下降。

最终

至此,系统进入了无级缩放的大型 站阶段,当 站流量增加时,应对的解决方案就是不断添加Web服务器、数据库服务器、以及缓存服务器。此时,大型 站的系统架构演变为图所示。

由图可知:

  1. 当浏览器访问一个包含属性的页面时,如果应用的缓存不存在,浏览器会加载文档,获取所有在清单文件中列出的文件,生成初始缓存。

  2. 当后续请求再次对该文档再次访问时,浏览器会直接从应用缓存中加载页面以及在清单文件中列出的资源。同时,浏览器还会向 对象发送一个表示检查的事件,以获取清单文件。

  3. 如果当前缓存的清单副本是最新的,浏览器将向window.applicationCache对象发送一个表示无须更新的事件,从而结束更新过程。如果在服务端修改了任何缓存资源,必须同时修改清单文件,这样浏览器才能知道要重新获取资源。

  4. 如果清单文件已经改变,那么文件中列出的所有文件会被重新获取并放到一个临时缓存中。对于每个加入到临时缓存中的文件,浏览器会向对象发送一个表示进行中的事件。

  5. 一旦所有文件都获取成功,它们会自动移动到真正的离线缓存中,并向window.applicationCache对象发送一个表示已经缓存的事件。鉴于文档早已经从缓存加载到浏览器中,所以更新后的文档不会重新渲染,直到页面重新加载。

注意:manifest文件中列出的资源URL必须和manifest本身使用同样的 络协议,详情可参考W3C相关的标准文档。

HTTP 1.1

HTTP 1.1有了较大的增强,缓存系统被形式化了,引入了实体标签 **e-tag 和 Cache-Control。

  • e-tag 是文件或对象的唯一标识。每次请求携带e-tage参数进行访问,文件是否被更新。

  • Cache-Control:相对过期,从客户端收到响应时间时开始计算,多少秒后缓存会过期。具体字段信息如下:

  • max-age:用来设置资源(representations)可以被缓存多长时间,单位为秒;

  • s-maxage:和max-age是一样的,不过它只针对代理服务器缓存而言;  - public:指示响应可被任何缓存区缓存;

  • private:只能针对个人用户,而不能被代理服务器缓存;

  • no-cache:强制客户端直接向服务器发送请求,也就是说每次请求都必须向服务器发送。服务器接收到请求,判断资源是否变更,是则返回新内容,否则返回304。

  • no-store:禁止一切缓存(这个是响应不被缓存的意思)

  • If-None-Match:第一次发送etag字段响应给客户端后,下次请求客户端会同时发送一个If-None-Match来判断数据是否发送变化,而它的值就是Etag的值

以Web浏览器使用 为例,如下图所示。

一般情况下,使用 Cache-Control/Expires 会配合 Last-Modified/ETag 一起使用,因为即使服务器设置缓存时间,当用户点击 刷新 按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将能够很好利用服务端的返回码304,从而减少响应开销。

通过在HTML页面的节点中加入meta标签,可告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。代码如下:

只不过,只有部分浏览器才支持这一用法,而且一般 缓存代理服务器都不支持,因为代理本身不解析 HTML 的内容。浏览器缓存能够极大地提升终端用户的体验,那么,用户在使用浏览器的时候,会有各种操作,如输入地址后回车、按F5刷新等等,这些行为对缓存的影响如下所示。

文件操作

对APP中的某些界面,可以采用文件缓存的方法。这种方法使用文件操作的相关API得到文件的最后修改时间,与当前时间判断是否过期,从而实现缓存效果。

但需要注意的是,不同类型文件的缓存时间不一样。比如:
文件类型

  • 图片文件的内容是相对不变的,直到最终被清理掉,APP可以永远读取缓存中的图片内容。
  • 配置文件中的内容是可能更新的,需要设置一个可接受的缓存时间。同时,不同环境下的缓存时间标准也是不一样的。

络环境

  • WiFi 络环境下,缓存时间可以设置短一点,一是 速较快,二是不产生流量费。

  • 移动数据流量环境下,缓存时间可以设置长一点,节省流量,而且用户体验也更好。

在iOS开发中,SDWebImage是一个很棒的图片缓存框架,主要类组成的结构如下所示。

缓存就会用!它架构还没听过?分布式多级缓存架构知识大瓶装,25 张图打包拎走

SDWebImage 是个比较大的类库,提供一个UIImageView的类以支持远程加载来自 络的图片,具有缓存管理、异步下载、同一个URL下载次数控制和优化等特征。使用时,只需要在头文件中引入 即可调用异步加载图片方法:

URL是图片的地址

  • placeholderImage是 络图片在尚未加载成功时显示的图像
  • SDWebImageOptions是相关选项。

默认情况下,SDWebImage会忽略Header中的缓存设置,将图片以URL为key进行保存,URL与图片是一一映射关系。在APP请求同一个URL时,SDWebImage会从缓存中取得图片。将第三个参数设置为SDWebImageRefreshCached就可以实现图片更新操作,例如:

SDWebImage中有两种缓存

  • 磁盘缓存
  • 内存缓存

框架都提供了相应的清理方法:

要注意的是,在iOS7中,缓存机制做了修改,使用上述两个方法只清除了SDWebImage的缓存,没有清除系统的缓存,所以可以在清除缓存的代理中添加以下代码:

最后:

  • 缓存根据存在方式有系统、硬件、软件三类。
  • 软件根据场景客户端、 络、分布式缓存
  • 用户体验:即用户在使用一个产品或系统之前、使用期间和使用之后的全部感受。
  • 系统性能指标有响应时间、延迟时间、吞吐量,并发用户数和资源利用率等几方面
  • 站架构演讲,经历起步、发展、中期、高手增长、后期
  • 客户端缓存分为页面缓存、浏览器缓存、APP缓存

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91280 人正在系统学习中

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年9月8日
下一篇 2020年9月8日

相关推荐