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

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

那缓存若是站在网站架构的角度,你知道它的设计原理和影响做用吗?php

絮叨

在商业的世界里,常说的一句话是 <span style="color:#773098;font-weight:bold;">"现金为王"。在互联网、移动互联网乃至整个软件技术的世界里面,与之相近的就是 <span style="color:#773098;font-weight:bold;">"缓存为王"html

为什么这么说呢?

试想一下,你个完整的网络请求(HTTP、SOAP、RPC等),若是在执行过程的某个部分尚有缓存,是否是就能提早响应给客户端呢? webpack

为什么如今不少中大型公司在面试时,对缓存的应用、原理、高可用等一系列问题,都一扑啦的扔给你,让你难以招架。缘由都在这。ios

什么是缓存?

缓存:存储在计算机上的一个原始数据复制,以便于访问
--维基百科

缓存是系统快速响应中的一种关键技术,是一组被保存起来以备未来使用的东西。介于应用开发和系统开发之间,是产品经理常常估计不到的地方,也是技术架构设计中的非功能性约束。nginx

应用开发我知道,这系统缓存是个什么状况呀,小吒哥?
不要着急,日后面看

什么是多级缓存架构?

顾名思义,由多个维度共同组成的缓存工程。由于缓存在不一样的场景有着不一样的意义。采用的技术手段也不一样。 web

按缓存存在形式分:面试

  1. 硬件缓存(如CPU、硬盘等)
  2. 操做系统缓存
  3. 软件缓存
系统缓存是什么?

操做系统是管理计算机硬件与软件资源的计算机程序,而硬、软件件运行速度的快慢基本由缓存决定,缓存的容量越大,相应的硬件运行速度也就越快。因此系统缓存就是操做系统调用硬件资源(内存、文件等)和调用应用程序时,可以启动加速执行的做用。ajax

总结:操做系统存调用涉及到有缓存的部分,均可算系统缓存

软件运行都需创建在操做系统之上,在运行时须要把程序装载到内存中,<span style="color:#773098;font-weight:bold;">但软件执行操做内存时都是基于虚拟内存映射的机制,并非直接操做物理内存。虚拟内存以块表(内存块组成的表格)的形式来存储相关资源。算法

注:物理内存组成上由多个方块状的元素构成,该元素是内存管理的最小单位。每个元素有8个小电容,存储8个bit,即1字节。
是否是和磁盘块差很少, ^_^ 。吒吒辉懂你呀

为提升系统的存取速度,在 <span style="color:#773098;font-weight:bold;"> 地址映射机制中增长了一个小容量的联想寄存器,即块表。
shell

<span style="color:#773098;font-weight:bold;"> 用来存放当前访问最频繁的少数活动页面的页数。当某用户需存取数据时,根据数据所在的逻辑页号在块表中找到对应的内存块号,再联系其页内地址,造成物理地址。

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

若是块表中没有相应的逻辑页号,则地址映射仍然能够经过内存中的页表进行操做,只是它获得是空闲块号,必须将该块号填入块表中的空闲区。若是块表中没有空闲区,则根据淘汰算法淘汰块表中的某一行,在填入新的页号和块号。

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

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

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

平常开发常使缓存软件,根据软件系统所处位置不一样,可分

  • 客户端缓存
  • 网络缓存
  • 服务端缓存

多级缓存就相似金字塔模式。从上到下依次递减。相似于一个漏斗来过滤流量请求。若是绝大多数请求在客户端和网络交互的部分就抵消,那后端服务的压力就会大大减小。

为何使用多级缓存架构?

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

聊聊用户体验

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

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

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

什么是用户体验?

ISO 9241-210 标准将用户体验定义为 <span style="color:#773098;font-weight:bold;">“人们对正在使用或指望使用的产品、系统或者服务的认知印象和回应” 。所以,用户体验是主观的,且注重实际应用。

<span style="color:#773098;font-weight:bold;">用户体验:即用户在使用一个产品或系统以前、使用期间和使用以后的所有感觉,包括情感、信仰、喜爱、认知印象、生理反应、心理反应、行为和成就等各个方面。

ISO标准也暗示了可用性也能够做为用户体验的一个方面,<span style="color:#773098;font-weight:bold;">“可用性标准能够用来评估用户体验的一些方面”。不过,该ISO标准并无进一步阐述用户体验和系统可用性之间的具体关系。显然,这二者是相互重叠的概念。

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

影响用户体验的因素

影响用户体验的三因素:

  1. 使用者的状态
  2. 系统性能
  3. 环境

<span style="color:#773098;font-weight:bold;">系统性能是软件产品自身对用户体验最关键的因素。 因感觉软件性能的主体是人,<span style="color:#773098;font-weight:bold;">不一样的人对于一样的软件可能有不一样的主观感觉,并且对于软件性能关心的视角也不一样。

系统性能是一种非功能特性,<span style="color:#773098;font-weight:bold;">它关注的不是某种特定的功能,而是在完成该功能时所展现出的及时性。

关于系统的性能

系统性能的指标通常包括 响应时间、延迟时间、吞吐量,并发用户数和资源利用率 等几方面。

响应时间

响应时间是指系统对用户请求作出响应的时间,与人对软件性能的主观感觉是一致的,完整地记录了整个系统处理请求的时间。

通常响应时间根据不一样项目中的业务场景都会有确切的值,例:一个请求需保证在100ms、200ms之内。

你家首页响应需多少时间?

因为一个系统一般会提供许多功能,而不一样功能的处理逻辑也千差万别,于是不一样功能的响应时间也不尽相同,甚至同一功能在不一样输入数据的状况下,响应时间也不相同。

因此,咱们常说的响应时间一般指该软件系统 <span style="color:#773098;font-weight:bold;">全部功能的平均响应时间 或者 <span style="color:#773098;font-weight:bold;">全部功能中的最大响应时间。

有时候也须要对 <span style="color:#773098;font-weight:bold;">每一个或每组功能讨论其平均响应时间和最大响应时间。

在讨论软件性能时,咱们更关心所开发软件自身的 <span style="color:#773098;font-weight:bold;">“响应时间”

好比:PHP响应时间就是从接受到nginx请求后,并完成业务处理而后响应给nginx所消耗的时间。而用户就看发送请求到看到页面所需的时间

前者是整个软件自身的响应,后者是用户请求响应的时间。观看角度不一样

就这样,咱们能够把 用户感觉到的响应时间 划分为 <span style="color:#773098;font-weight:bold;"> 呈现时间和系统响应时间

  • 呈现时间:客户端在接收到系统数据时呈现页面所需的时间,即页面渲染加载时间
  • 系统响应时间:**从客户端发送请求开始计时,直到

服务器响应给客户端所需的时间**

还能够把“系统响应时间”进一步分解为网络传输时间和“应用延迟时间”

  • 网络传输时间: 数据在客户端和服务器端进行传输的时间
  • 应用延迟时间: 系统实际处理请求业务所需时间
之后谈优化,那就应该从整个请求链路里着手,针对呈现、网络传输、应用处理时间

吞吐量

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

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

那我网站的吞吐量怎么计算呢? 做为小吒的我,仍是补了课的
要计算吞吐量首先要看你的时间换算和流量状况。
  • 单位时间划分

假设一个发布系统的广告页要知足30分钟内总访问量为500w。
那平均QPS为: 500w/(30*60) = 2778,大概3000 QPS /S(要预留空间)

  • 按天算

假设某个信息分类网站首页日均PV约8000w
那平均QPS为: 一天按照4W秒算(晚上不计算),8000w/4w= 2000,大概2000QPS。

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

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

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

无并发的应用都是单机应用,对于互联网或者移动互联网上的产品而言。

并发用户数

并发用户数是指系统能够同时承载的正常使用系统功能的用户数量,值越大,那处理能力就越强。

资源利用率反映的是在一段时间内资源平均被占用的状况。

从浏览器--->网络--->应用服务器--->数据库,经过在各个层面应用缓存技术,将大幅提升提高整个系统的性能。

例如:缓存离客户端更近,从缓存请求内容比从源服务器所用时间更少,呈现速度更快,系统就显得更灵敏。缓存数据的重复使用,大大下降了用户的带宽使用,其实也是一种变相的省钱(若是流量要付费的话),同时保证了带宽请求在一个低水平上,更容易维护。

因此,使用 <span style="color:#773098;font-weight:bold;"> 缓存技术,能够下降系统的响应时间,减小网络传输时间和应用延迟时间,进而提升了系统的吞吐量,增长了系统的并发用户数
利用缓存还能够最小化系统的工做量,使用了缓存就能够没必要反复从数据源中查找,缓存所建立或提供的同一条数据更好地利用了系统的资源。

所以,缓存是系统调优时经常使用且行之有效的手段,不管是操做系统仍是应用系统,缓存策略无处不在。“缓存为王”本质上是系统性能为王,对用户而言就是用户体验为王。

网站架构缓存演进

起步

最初的网站可能就是一台物理主机,放在IDC或者租用的是云服务器,上面只运行着 <span style="color:#773098;font-weight:bold;">应用服务器和数据库,LAMP(Linux Apache MySQL PHP)就是这样流行起来的。

发展

因为网站具有必定的特点,吸引了部分用户的访问,逐渐会发现系统的压力愈来愈大,响应速度愈来愈慢,而这个时候比较明显的每每是 <span style="color:#773098;font-weight:bold;">数据库与应用 的互相影响,因而将应用服务器和数据库服务器从物理上分离开来,变成了两台机器。让其不在互相影响,来支撑更高的流量。

### 中期
随着访问网站的人数愈来愈多,响应速度又开始变慢了,多是 <span style="color:#773098;font-weight:bold;">访问数据库的操做太多,致使数据链接竞争激烈,所以缓存开始登场。

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

若想经过缓存机制来减小数据库链接资源的竞争和对数据库读的压力,那么可以下选择:

  • <span style="color:#773098;font-weight:bold;">静态页面缓存: 这样程序上能够不作修改,就可以很好地减小对Web服务器的压力以及减小对数据库链接资源的竞争。
  • <span style="color:#773098;font-weight:bold;">动态缓存: 将动态页面里相对静态的部分也缓存起来,所以考虑采用相似的页面片断缓存策略(经过nginx、Apache配置实现动态缓存)

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

那我数据库写呢?

此刻流量上升,主要针对访问,写请求也会上升,但性能瓶颈在于数据库的读操做上。能够说写还构不成太大的威胁。若是写不够,那只能扩容多个实例来应对写的不足。

高速增加期

随着访问量的持续增长,系统又开始变慢,怎么办?

使用 <span style="color:#773098;font-weight:bold;">数据缓存,将系统中重复获取的数据信息从数据库加载到本地,同时下降了数据库的负载。 随着系统访问量的再度增长,应用服务器又扛不住了,就开始增长Web服务器。

那如何保持应用服务器中数据缓存信息的同步呢?

例如: 以前缓存的用户数据等,这个时候一般会开始使用缓存同步机制以及共享文件系统或共享存储等。 在享受了一段时间的访问量高速增加后,系统再次变慢。

<span style="color:#773098;font-weight:bold;">开始数据库调优,优化数据库自身的缓存,接下来是采用数据库集群以及分库分表的策略

分库分表的规则是有些复杂的,考虑增长一个通用的框架来实现分库分表的数据访问,这个就是 数据访问层(Data Access Layer,DAL)。
  • 缓存同步机制:每台web服务器,都会是保存一份缓存文件,那数据之间就须要缓存的同步机制来完成。
  • 共享存储:共享存储是指两个或多个处理机共用一个主存储器的并行体系结构,像Redis。
  • 共享文件系统:两台机器之间的文件系统可以更加紧密地结合在一块儿,让一台主机上的用户能够像使用本机的文件系统同样使用远程机的文件系统。像Samba和NFS。

后期

该阶段可能会发现以前的缓存同步方案会出现问题,<span style="color:#773098;font-weight:bold;">由于数据量太大,致使如今不太可能将缓存存储在本地后再同步,这样会形成同步的时间延迟从而增大响应时间、数据不一致性,数据库耦合缓存。
因而分布式缓存终于来了,将大量的数据缓存转移到分布式缓存上。

若是使用共享文件系统或共享存储有啥问题?
  • 共享存储:多个服务访问一个存储,那么容易形成单例性能不足的问题和。若是是并发读写可能会致使缓存和数据不一致问题。
  • 共享文件: 多个服务压力太大,因文件I/O开销大。性能会致使降低。

最终

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

纵观网站架构的发展历程,缓存技术每每就是解除烦恼的灵丹妙药,这再次证实了什么是缓存为王。

客户端缓存的实施方案

客户端缓存相对于其余端的缓存而言,要简单一些,一般是和服务端以及网络侧的应用或缓存配合使用。

在互联网应用中,根据应用区分有二大类。

  • B/S架构:页面缓存和浏览器缓存
  • 移动应用:APP自身所使用的缓存

页面缓存

页面缓存是什么?
页面缓存有两层含义:
  • 客户端将页面自身对某些元素或所有元素进行缓存。简称离线应用缓存
  • 服务端将静态页面或动态页面的元素进行缓存,而后给客户端使用。简称页面自身缓存。

页面缓存是将以前渲染的页面保存为静态文件,当用户再次访问时能够避开网络链接,从而减小负载,提高性能和用户体验。

随着单页面应用(Single Page Application,SPA)的普遍使用,加之HTML5支持了离线缓存和本地存储,大部分BS应用的页面缓存均可以举重若轻了。

在HTML5中使用本地缓存的方法,示例代码以下:

localStorage.setItem("mykey","吒吒辉")
localStorage.getItem("mykey","吒吒辉")
localStorage.removeItem("mykey")
localStorage.clear()

什么是单页面应用?

SPA是在 Web 设计上使用单一页面,利用 JavaScript 操做 Dom 的技术实现各类应用。此模式下一个系统只加载一次资源,以后的操做交互、数据交互是经过路由、ajax来进行,页面并无刷新。

常见的路由形式如:http:.//xxx/shell.htm1#page1
通常在Vue下使用很明显。像商城活动页、登陆页这种都是很好的SPA落地实践。


HTML5提供的离线应用缓存机制,使得网页应用能够离线使用(无网络也可访问),这种机制在浏览器上支持度很是广,能够放心地使用该特性来加速页面的访问。开启离线缓存的步骤以下:

  1. 准备用于描述页面须要缓存的资源列表清单文件 (manifest text/cache-manifest)
注:manifest 文件须要配置正确的 MIME-type,即 "text/cache-manifest"。必须在 web 服务器上进行配置。

例:nginx要修改配置目录下的 mime.types 文件,添加manifest文件映射:

text/cache-manifest            manifest;
  1. 在须要离线使用的页面中的 html 里添加 manifest属性,指定缓存清单文件的路径。 离线缓存的工做流如图所示。

`
目前html标签的manifest属性已废弃了,可移步 webpack。
`

由图可知:

  1. 当浏览器访问一个包含manifest属性的页面时,若是应用的缓存不存在,浏览器会加载文档,获取全部在清单文件中列出的文件,生成初始缓存。
  2. 当后续请求再次对该文档再次访问时,浏览器会直接从应用缓存中加载页面以及在清单文件中列出的资源。同时,浏览器还会向 window.applicationCache 对象发送一个表示检查的事件,以获取清单文件。
  3. 若是当前缓存的清单副本是最新的,浏览器将向window.applicationCache对象发送一个表示无须更新的事件,从而结束更新过程。若是在服务端修改了任何缓存资源,必须同时修改清单文件,这样浏览器才能知道要从新获取资源。
  4. 若是清单文件已经改变,那么文件中列出的全部文件会被从新获取并放到一个临时缓存中。对于每一个加入到临时缓存中的文件,浏览器会向 window.applicationCache 对象发送一个表示进行中的事件。
  5. 一旦全部文件都获取成功,它们会自动移动到真正的离线缓存中,并向window.applicationCache对象发送一个表示已经缓存的事件。鉴于文档早已经从缓存加载到浏览器中,因此更新后的文档不会从新渲染,直到页面从新加载。
注意:manifest文件中列出的资源URL必须和manifest自己使用一样的网络协议,详情可参考W3C相关的标准文档。

*

浏览器缓存

浏览器缓存是根据一套与服务器约定的规则进行工做的,工做规则很简单:检查以确保副本为最新,一般只要一次会话请求

浏览器会在硬盘上专门开辟一个空间来存储资源副本做为缓存

在用户触发 <span style="color:#773098;font-weight:bold;">后退操做或点击 一个以前看过连接的时候,浏览器缓存会很管用。若是访问系统中的同一张图片,该图片能够从浏览器缓存中调出并几乎当即显现出来。

HTTP1.0

对浏览器而言,HTTP1.0提供了一些很基本的缓存特性,参数例如:

  • 在服务器侧设置 <span style="color:#773098;font-weight:bold;">Expires的HTTP头 来告诉客户端在从新请求文件以前缓存多久是有效的.
  • 请求经过 <span style="color:#773098;font-weight:bold;">if-modified-since 的条件判断使用缓存。
  • Last-Modified:Last-Modified是响应头,web容器会把最后修改时间告诉客户端

每次请求web容器时会先检查客户端缓存资源是否还有效,无效则会把上次服务端响应的最后修改时间做为 If-Modified-Since 的值发送给服务器进行判断,若是文件没有改变,服务器采用 <span style="color:#773098;font-weight:bold;">304-Not Modified作响应头和一个为空的响应体。客户端收到304响应,就可使用缓存的文件版本了。

为何客户端无效,还要发送HTTP请求来判断文件是否修改呢?

若是缓存资源有效那确实直接来读取客户端缓存,不须要发送HTTP请求。但有一些状况就需注意,好比当用户按F5或者点击Refresh按钮的时候就算对于有Expires的URI,同样也会发一个HTTP请求出去,因此就须要经过Last-Modified来判断。

并且客户端和服务端的时间可能不同,这样就会致使客户端已过时,但服务端并无。若是有判断机制,那么响应就会减小响应体的数据发送。 或者客户端只是单纯的 Expires 过时,但资源并没改变,这时就须要检查文件是否有变化。

HTTP 1.1

HTTP 1.1有了较大的加强,缓存系统被形式化了,引入了实体标签 **<span style="color:#773098;font-weight:bold;">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浏览器使用 e-tag 为例,以下图所示。

    在配置了 Last-Modified/ETag 的状况下,浏览器再次访问统一URI的资源时,仍是会发送请求到服务器询问文件是否已经修改,若是没有,服务器会生成304-Not Modified应答和一个空的响应体给浏览器,浏览器则直接从本地缓存取数据;若是数据有变化,就将整个数据从新发给浏览器。

    汇总

    Last-Modified/ETag 与 Cache-Control/Expires的做用是不同的。前者是每次询问实体版本是否有变化,后者是直接检查本地的缓存还在有效的时间范围内,若是在就不会发送任何请求。

    • 二者一块儿使用时,Cache-Control/Expires的优先级要高于Last-Modified/ETag。
    当本地副本根据 Cache-Control/Expires 判断是否还在有效期内,若是不在,则会再次发送请求去服务器询问修改时间(Last-Modified)或实体标识(e-tag)。

    Cache-Control与Expires的功能一致,都是指当前资源的有效期,控制浏览器是直接从浏览器缓存取数据仍是从新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,若是同时设置的话,其优先级高于Expires。

    通常状况下,使用 Cache-Control/Expires 会配合 Last-Modified/ETag 一块儿使用,由于即便服务器设置缓存时间,当用户点击 <span style="color:#773098;font-weight:bold;"> 刷新 按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将可以很好利用服务端的返回码304,从而减小响应开销。

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

    <META HTTP-EQUIV="Pragma" CONTENT="no-cache">

    只不过,只有部分浏览器才支持这一用法,并且通常 <span style="color:#773098;font-weight:bold;"> 缓存代理服务器都不支持,由于代理自己不解析 HTML 的内容。 浏览器缓存可以极大地提高终端用户的体验,那么,用户在使用浏览器的时候,会有各类操做,如输入地址后回车、按F5刷新等等,这些行为对缓存的影响以下所示。

      • -

    APP端缓存

    尽管混合编程(hybrid programming)已成为时尚,吵在尖端,但移动互联网目前仍是原生应用(APP)的天下。不管大小型APP,灵活的缓存不只大大减轻了服务器的压力,并且会因更快速的用户体验而方便用户。<span style="color:#773098;font-weight:bold;"> 如何把APP 缓存对于业务组件透明,以及APP缓存数据的及时更新,是APP缓存可否成功应用起来的关键。

    组件透明是什么?

    即组件对调用者来讲没有什么影响,也不须要维护。开箱即用。

    APP缓存可以使用那些缓存?

    APP能够将内容缓存在 <span style="color:#773098;font-weight:bold;">内存、文件或本地数据库(例如SQLite)中,但基于 <span style="color:#773098;font-weight:bold;"> 内存的缓存 要谨慎使用。

    本地库操做

    APP使用数据库缓存的方法:

    • 在下载完数据文件后,把文件的相关信息(如URL、路径、下载时间、过时时间等)存放到数据库.
    • 等下次请求下载的时候,根据URL先从数据库中查询,若是查询到当前时间并未过时,就根据路径读取本地文件,实现缓存的效果。

    优势:方法具备灵活存放文件的属性,进而提供了很大的扩展性,能够为其余的功能提供良好的支持。
    缺点:信息存储过多,存储容量会下降。因此要根据业务选择合适主要的信息存储

    <span style="color:#773098;font-weight:bold;">注意数据库缓存的清理机制

    文件操做

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

    但须要注意的是,<span style="color:#773098;font-weight:bold;">不一样类型文件的缓存时间不同。好比:
    <span style="color:#773098;font-weight:bold;">文件类型

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

    <span style="color:#773098;font-weight:bold;">网络环境

    • WiFi网络环境下,缓存时间能够设置短一点,一是网速较快,二是不产生流量费。
    • 移动数据流量环境下,缓存时间能够设置长一点,节省流量,并且用户体验也更好。

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

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

    (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;

    URL是图片的地址

    • placeholderImage是网络图片在还没有加载成功时显示的图像
    • SDWebImageOptions是相关选项。

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

    NSURL *url = [NSURL URLWithString:@"http://www.zhazhahui.com/image.png"];
    UIImage *defaultImage = [UIImage imageNamed:@"zhazhahui.png"];
    
    [self.imageView setImageWithURL:url placeholderImage:defaultImage options:SDWebImageRefreshCached];

    SDWebImage中有两种缓存

    • 磁盘缓存
    • 内存缓存

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

    [[[SDWebImageManager sharedManager] imageCache] clearDisk]; 
    [[[SDWebImageManager sharedManager] imageCache] clearMemory];
    要注意的是,在iOS7中,缓存机制作了修改,使用上述两个方法只清除了SDWebImage的缓存, 没有清除系统的缓存,因此能够在清除缓存的代理中添加如下代码:
    [[NSURLCache sharedURLCache] removeAllCachedResponses];

    最后:

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

    以上就是本文分享,但内容未完,这仍是开胃小菜。如有帮助,欢迎关注、分享。

    需获取本系列总结大纲直接公众号后台回复“分布式缓存”便可免费领取!!!

    絮絮不休

    其实,大纲很早就写好了,但对里面内容的呈现方式,细节原理就一直不知道如何撰写才能达到明朗的效果。

    这文章花了我很是多时间。哎,菜就是菜,吒吒辉我也不找借口了。。。 吒就是吒

    最近吒吒辉创了技术交流群,主题就是 【知识盛宴】,你们一块儿每周攻克一个难题,充分进行自我能力迭代提高,不单纯技术额!!!

    有兴趣的读者,能够扫一扫吒吒辉微信二维码,备注 「加群」 便可。据说里面的人说话又好听,各个都是人才。

    若是你们在阅读过程当中,发现了不理解或有错误的地方,欢迎跟在底部留言,大家的每一条留言,吒吒辉都会回复。

    若有帮助,欢迎关注、分享+收藏额,微信搜索【莲花童子哪吒】