A. java缓存技术有哪些
常见的java缓存框架有:
OSCache
OSCache是个一个广泛采用的高性能的J2EE缓存框架,OSCache能用于任何Java应用程序的普通的缓存解决方案。
OSCache有以下特点:
缓存任何对象,你可以不受限制的缓存部分jsp页面或HTTP请求,任何java对象都可以缓存。
拥有全面的API--OSCache API给你全面的程序来控制所有的OSCache特性。
永久缓存--缓存能随意的写入硬盘,因此允许昂贵的创建(expensive-to-create)数据来保持缓存,甚至能让应用重启。
支持集群--集群缓存数据能被单个的进行参数配置,不需要修改代码。
缓存记录的过期--你可以有最大限度的控制缓存对象的过期,包括可插入式的刷新策略(如果默认性能不需要时)。
官方网站 http://www.opensymphony.com/oscache/
Java Caching System
JSC(Java Caching System)是一个用分布式的缓存系统,是基于服务器的java应用程序。它是通过提供管理各种动态缓存数据来加速动态web应用。
JCS和其他缓存系统一样,也是一个用于高速读取,低速写入的应用程序。
动态内容和报表系统能够获得更好的性能。
如果一个网站,有重复的网站结构,使用间歇性更新方式的数据库(而不是连续不断的更新数据库),被重复搜索出相同结果的,就能够通过执行缓存方式改进其性能和伸缩性。
官方网站 http://jakarta.apache.org/turbine/jcs/
EHCache
EHCache 是一个纯java的在进程中的缓存,它具有以下特性:快速,简单,为Hibernate2.1充当可插入的缓存,最小的依赖性,全面的文档和测试。
官方网站 http://ehcache.sourceforge.net/
JCache
JCache是个开源程序,正在努力成为JSR-107开源规范,JSR-107规范已经很多年没改变了。这个版本仍然是构建在最初的功能定义上。
官方网站 http://jcache.sourceforge.net/
ShiftOne
ShiftOne Java Object Cache是一个执行一系列严格的对象缓存策略的Java lib,就像一个轻量级的配置缓存工作状态的框架。
官方网站 http://jocache.sourceforge.net/
SwarmCache
SwarmCache是一个简单且有效的分布式缓存,它使用IP multicast与同一个局域网的其他主机进行通讯,是特别为集群和数据驱动web应用程序而设计的。SwarmCache能够让典型的读操作大大超过写操作的这类应用提供更好的性能支持。
SwarmCache使用JavaGroups来管理从属关系和分布式缓存的通讯。
官方网站 http://swarmcache.sourceforge.net
TreeCache / JBossCache
JBossCache是一个复制的事务处理缓存,它允许你缓存企业级应用数据来更好的改善性能。缓存数据被自动复制,让你轻松进行JBoss服务器之间 的集群工作。JBossCache能够通过JBoss应用服务或其他J2EE容器来运行一个MBean服务,当然,它也能独立运行。
JBossCache包括两个模块:TreeCache和TreeCacheAOP。
TreeCache --是一个树形结构复制的事务处理缓存。
TreeCacheAOP --是一个“面向对象”缓存,它使用AOP来动态管理POJO(Plain Old Java Objects)
注:AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向方面编程。
官方网站 http://www.jboss.org/procts/jbosscache
WhirlyCache
Whirlycache是一个快速的、可配置的、存在于内存中的对象的缓存。它能够通过缓存对象来加快网站或应用程序的速度,否则就必须通过查询数据库或其他代价较高的处理程序来建立。
B. 什么是Java缓存技术Cache
java缓存技术
一、什么是缓存
1、Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问
2、凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之为 Cache
二、缓存的分类
1、基于web应用的系统架构图
2、在系统架构的不同层级之间,为了加快访问速度,都可以存在缓存
操作系统磁盘缓存->减少磁盘机械操作
数据库缓存->减少文件系统I/O
应用程序缓存->减少对数据库的查询
Web服务器缓存->减少应用服务器请求
客户端浏览器缓存->减少对网站的访问。
C. 常用的缓存技术
第一章 常用的缓存技术
1、常见的两种缓存
本地缓存:不需要序列化,速度快,缓存的数量与大小受限于本机内存
分布式缓存:需要序列化,速度相较于本地缓存较慢,但是理论上缓存的数量与大小无限(因为缓存机器可以不断扩展)
2、本地缓存
Google guava cache:当下最好用的本地缓存
Ehcache:spring默认集成的一个缓存,以spring cache的底层缓存实现类形式去操作缓存的话,非常方便,但是欠缺灵活,如果想要灵活使用,还是要单独使用Ehcache
Oscache:最经典简单的页面缓存
3、分布式缓存
memcached:分布式缓存的标配
Redis:新一代的分布式缓存,有替代memcached的趋势
3.1、memcached
经典的一致性hash算法
基于slab的内存模型有效防止内存碎片的产生(但同时也需要估计好启动参数,否则会浪费很多的内存)
集群中机器之间互不通信(相较于Jboss cache等集群中机器之间的相互通信的缓存,速度更快<--因为少了同步更新缓存的开销,且更适合于大型分布式系统中使用)
使用方便(这一点是相较于Redis在构建客户端的时候而言的,尽管redis的使用也不困难)
很专一(专做缓存,这一点也是相较于Redis而言的)
3.2、Redis
可以存储复杂的数据结构(5种)
strings-->即简单的key-value,就是memcached可以存储的唯一的一种形式,接下来的四种是memcached不能直接存储的四种格式(当然理论上可以先将下面的一些数据结构中的东西封装成对象,然后存入memcached,但是不推荐将大对象存入memcached,因为memcached的单一value的最大存储为1M,可能即使采用了压缩算法也不够,即使够,可能存取的效率也不高,而redis的value最大为1G)
hashs-->看做hashTable
lists-->看做LinkedList
sets-->看做hashSet,事实上底层是一个hashTable
sorted sets-->底层是一个skipList
有两种方式可以对缓存数据进行持久化
RDB
AOF
事件调度
发布订阅等
4、集成缓存
专指spring cache,spring cache自己继承了ehcache作为了缓存的实现类,我们也可以使用guava cache、memcached、redis自己来实现spring cache的底层。当然,spring cache可以根据实现类来将缓存存在本地还是存在远程机器上。
5、页面缓存
在使用jsp的时候,我们会将一些复杂的页面使用Oscache进行页面缓存,使用非常简单,就是几个标签的事儿;但是,现在一般的企业,前台都会使用velocity、freemaker这两种模板引擎,本身速度就已经很快了,页面缓存使用的也就很少了。
总结:
在实际生产中,我们通常会使用guava cache做本地缓存+redis做分布式缓存+spring cache就集成缓存(底层使用redis来实现)的形式
guava cache使用在更快的获取缓存数据,同时缓存的数据量并不大的情况
spring cache集成缓存是为了简单便捷的去使用缓存(以注解的方式即可),使用redis做其实现类是为了可以存更多的数据在机器上
redis缓存单独使用是为了弥补spring cache集成缓存的不灵活
就我个人而言,如果需要使用分布式缓存,那么首先redis是必选的,因为在实际开发中,我们会缓存各种各样的数据类型,在使用了redis的同时,memcached就完全可以舍弃了,但是现在还有很多公司在同时使用memcached和redis两种缓存。
D. 电脑的缓存指的是什么
CPU缓存(Cache
Memory)位于CPU与内存之间的临时存储器,它的容量比内存小但交换速度快。在缓存中的数据是内存中的一小部分,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可避开内存直接从缓存中调用,从而加快读取速度。由此可见,在CPU中加入缓存是一种高效的解决方案,这样整个内存储器(缓存+内存)就变成了既有缓存的高速度,又有内存的大容量的存储系统了。缓存对CPU的性能影响很大,主要是因为CPU的数据交换顺序和CPU与缓存间的带宽引起的。
缓存是为了解决CPU速度和内存速度的速度差异问题。内存中被CPU访问最频繁的数据和指令被复制入CPU中的缓存,这样CPU就可以不经常到象“蜗牛”一样慢的内存中去取数据了,CPU只要到缓存中去取就行了,而缓存的速度要比内存快很多。
这里要特别指出的是:
1.因为缓存只是内存中少部分数据的复制品,所以CPU到缓存中寻找数据时,也会出现找不到的情况(因为这些数据没有从内存复制到缓存中去),这时CPU还是会到内存中去找数据,这样系统的速度就慢下来了,不过CPU会把这些数据复制到缓存中去,以便下一次不要再到内存中去取。
2.因为随着时间的变化,被访问得最频繁的数据不是一成不变的,也就是说,刚才还不频繁的数据,此时已经需要被频繁的访问,刚才还是最频繁的数据,现在又不频繁了,所以说缓存中的数据要经常按照一定的算法来更换,这样才能保证缓存中的数据是被访问最频繁的。
缓存的工作原理
[编辑本段]
缓存的工作原理是当CPU要读取一个数据时,首先从缓存中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就用相对慢的速度从内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。
正是这样的读取机制使CPU读取缓存的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在缓存中,只有大约10%需要从内存读取。这大大节省了CPU直接读取内存的时间,也使CPU读取数据时基本无需等待。总的来说,CPU读取数据的顺序是先缓存后内存。
一级缓存和二级缓存
[编辑本段]
为了分清这两个概念,我们先了解一下RAM
。RAM和ROM相对的,RAM是掉电以后,其中的信息就消失那一种,ROM在掉电以后信息也不会消失那一种。
RAM又分两种,一种是静态RAM,SRAM;一种是动态RAM,DRAM。前者的存储速度要比后者快得多,我们现在使用的内存一般都是动态RAM。
有的菜鸟就说了,为了增加系统的速度,把缓存扩大不就行了吗,扩大的越大,缓存的数据越多,系统不就越快了吗?缓存通常都是静态RAM,速度是非常的快,
但是静态RAM集成度低(存储相同的数据,静态RAM的体积是动态RAM的6倍),
价格高(同容量的静态RAM是动态RAM的四倍),
由此可见,扩大静态RAM作为缓存是一个非常愚蠢的行为,
但是为了提高系统的性能和速度,我们必须要扩大缓存,
这样就有了一个折中的方法,不扩大原来的静态RAM缓存,而是增加一些高速动态RAM做为缓存,
这些高速动态RAM速度要比常规动态RAM快,但比原来的静态RAM缓存慢,
我们把原来的静态ram缓存叫一级缓存,而把后来增加的动态RAM叫二级缓存。
一级缓存和二级缓存中的内容都是内存中访问频率高的数据的复制品(映射),它们的存在都是为了减少高速CPU对慢速内存的访问。
通常CPU找数据或指令的顺序是:先到一级缓存中找,找不到再到二级缓存中找,如果还找不到就只有到内存中找了。
缓存的技术发展
[编辑本段]
最早先的CPU缓存是个整体的,而且容量很低,英特尔公司从Pentium时代开始把缓存进行了分类。当时集成在CPU内核中的缓存已不足以满足CPU的需求,而制造工艺上的限制又不能大幅度提高缓存的容量。因此出现了集成在与CPU同一块电路板上或主板上的缓存,此时就把
CPU内核集成的缓存称为一级缓存,而外部的称为二级缓存。一级缓存中还分数据缓存(Data
Cache,D-Cache)和指令缓存(Instruction
Cache,I-Cache)。二者分别用来存放数据和执行这些数据的指令,而且两者可以同时被CPU访问,减少了争用Cache所造成的冲突,提高了处理器效能。英特尔公司在推出Pentium
4处理器时,用新增的一种一级追踪缓存替代指令缓存,容量为12KμOps,表示能存储12K条微指令。
随着CPU制造工艺的发展,二级缓存也能轻易的集成在CPU内核中,容量也在逐年提升。现在再用集成在CPU内部与否来定义一、二级缓存,已不确切。而且随着二级缓存被集成入CPU内核中,以往二级缓存与CPU大差距分频的情况也被改变,此时其以相同于主频的速度工作,可以为CPU提供更高的传输速度。
二级缓存是CPU性能表现的关键之一,在CPU核心不变化的情况下,增加二级缓存容量能使性能大幅度提高。而同一核心的CPU高低端之分往往也是在二级缓存上有差异,由此可见二级缓存对于CPU的重要性。
CPU在缓存中找到有用的数据被称为命中,当缓存中没有CPU所需的数据时(这时称为未命中),CPU才访问内存。从理论上讲,在一颗拥有二级缓存的CPU中,读取一级缓存的命中率为80%。也就是说CPU一级缓存中找到的有用数据占数据总量的80%,剩下的20%从二级缓存中读取。由于不能准确预测将要执行的数据,读取二级缓存的命中率也在80%左右(从二级缓存读到有用的数据占总数据的16%)。那么还有的数据就不得不从内存调用,但这已经是一个相当小的比例了。目前的较高端的CPU中,还会带有三级缓存,它是为读取二级缓存后未命中的数据设计的—种缓存,在拥有三级缓存的CPU中,只有约5%的数据需要从内存中调用,这进一步提高了CPU的效率。
为了保证CPU访问时有较高的命中率,缓存中的内容应该按一定的算法替换。一种较常用的算法是“最近最少使用算法”(LRU算法),它是将最近一段时间内最少被访问过的行淘汰出局。因此需要为每行设置一个计数器,LRU算法是把命中行的计数器清零,其他各行计数器加1。当需要替换时淘汰行计数器计数值最大的数据行出局。这是一种高效、科学的算法,其计数器清零过程可以把一些频繁调用后再不需要的数据淘汰出缓存,提高缓存的利用率。
CPU产品中,一级缓存的容量基本在4KB到64KB之间,二级缓存的容量则分为128KB、256KB、512KB、1MB、2MB、4MB等。一级缓存容量各产品之间相差不大,而二级缓存容量则是提高CPU性能的关键。二级缓存容量的提升是由CPU制造工艺所决定的,容量增大必然导致CPU内部晶体管数的增加,要在有限的CPU面积上集成更大的缓存,对制造工艺的要求也就越高。
现在主流的CPU二级缓存都在2MB左右,其中英特尔公司07年相继推出了台式机用的4MB、6MB二级缓存的高性能CPU,不过价格也是相对比较高的,对于对配置要求不是太高的朋友,一般的2MB二级缓存的双核CPU基本也可以满足日常上网需要了。
E. 什么是Java缓存技术Cache
java缓存技术
一、什么是缓存
1、Cache是高速缓冲存储器
一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问
2、凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之为
Cache
二、缓存的分类
1、基于web应用的系统架构图
2、在系统架构的不同层级之间,为了加快访问速度,都可以存在缓存
操作系统磁盘缓存->减少磁盘机械操作
数据库缓存->减少文件系统I/O
应用程序缓存->减少对数据库的查询
Web服务器缓存->减少应用服务器请求
客户端浏览器缓存->减少对网站的访问。
F. 指令缓存的技术简介
CPU缓存(Cache Memory)位于CPU与内存之间的临时存储器,它的容量比内存小但交换速度快。在缓存中的数据是内存中的一小部分,但这一小部分是短时间内CPU即 将访问的,当CPU调用大量数据时,就可避开内存直接从缓存中调用,从而加快读取速度。由此可见,在CPU中加入缓存是一种高效的解决方案,这样整个内存储器(缓存+内存)就变成了既有缓存的高速度,又有内存的大容量的存储系统了。缓存对CPU的性能影响很大,主要是因为CPU的数据交换顺序和CPU与缓 存间的带宽引起的。
缓存的工作原理是当CPU要读取一个数据时,首先从缓存中查找,如果找到就立即读取并送给CPU处理;如果没有找到,就用相对慢的速度从内存中 读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。
正是这样的读取机制使CPU读取缓存的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在缓存中,只有 大约10%需要从内存读取。这大大节省了CPU直接读取内存的时间,也使CPU读取数据时基本无需等待。总的来说,CPU读取数据的顺序是先缓存后内存。
最早先的CPU缓存是个整体的,而且容量很低,英特尔公司从Pentium时代开始把缓存进行了分类。当时集成在CPU内核中的缓存已不足以满 足CPU的需求,而制造工艺上的限制又不能大幅度提高缓存的容量。因此出现了集成在与CPU同一块电路板上或主板上的缓存,此时就把 CPU内核集成的缓 存称为一级缓存,而外部的称为二级缓存。一级缓存中还分指令缓存(I-Cache)和数据缓存(D-Cache)。二者分别用来存放数据和执行这些数据的 指令,提高了处理器效能。英特尔公司在推出Pentium 4处理器时,还新增了一种一级追踪缓存,容量为12KB.
随着CPU制造工艺的发展,二级缓存也能轻易的集成在CPU内核中,容量也在逐年提升。再用集成在CPU内部与否来定义一、二级缓存,已不 确切。而且随着二级缓存被集成入CPU内核中,以往二级缓存与CPU大差距分频的情况也被改变,此时其以相同于主频的速度工作,可以为CPU提供更高的传 输速度。
二级缓存是CPU性能表现的关键之一,在CPU核心不变化的情况下,增加二级缓存容量能使性能大幅度提高。而同一核心的CPU高低端之分往往也是在二级缓存上有差异,由此可见二级缓存对于CPU的重要性。
CPU在缓存中找到有用的数据被称为命中,当缓存中没有CPU所需的数据时(这时称为未命中),CPU才访问内存。从理论上讲,在一颗拥有二级缓存的CPU中,读取一级缓存的命中率为80%。也就是说CPU一级缓存中找到的有用数据占数据总量的80%,剩下的20%从二级缓存中读取。由于不能准 确预测将要执行的数据,读取二级缓存的命中率也在80%左右(从二级缓存读到有用的数据占总数据的16%)。那么还有的数据就不得不从内存调用,但这已经 是一个相当小的比例了。
较高端的CPU中,还会带有三级缓存,它是为读取二级缓存后未命中的数据设计的—种缓存,在拥有三级缓存的CPU中,只有约 5%的数据需要从内存中调用,这进一步提高了CPU的效率。
G. 什么是高速缓存技术高速缓存的作用是什么
高速缓存英文是cache。一种特殊的存储器子系统,其中复制了频繁使用的数据,以利于CPU快速访问。存储器的高速缓冲存储器存储了频繁访问的 RAM 位置的内容及这些数据项的存储地址。当处理器引用存储器中的某地址时,高速缓冲存储器便检查是否存有该地址。如果存有该地址,则将数据返回处理器;如果没有保存该地址,则进行常规的存储器访问。因为高速缓冲存储器总是比主RAM 存储器速度快,所以当 RAM 的访问速度低于微处理器的速度时,常使用高速缓冲存储器。 高速缓存的作用: 在CPU开始执行任何指令之前,都会首先从内存中取得该条指令以及其它一些相关数据和信息。为了加快CPU的运行速度,几乎所有的芯片都采用两种不同类型的内部存储器,即高速缓存。缓存被用来临时存放一些经常被使用的程序片段或数据。 一级高速缓存是性能最好缓存类型,与解释指令和执行算术运算的处理单元一到构成CPU的核心。CPU可以在全速运行的状态下读取存放在一级高速缓存中的指令或数据。Intel的处理器产品一般都会具有32K的一级缓存,而象AMD或Via这种竞争对手的产品则会使用更多的一级缓存。 如果在一级缓存中没有找到所需要的指令或数据,处理器会查看容量更大的二级缓存。二级缓存既可以被集成到CPU芯片内部,也可以作为外部缓存。Pentium II处理器具有512K的二级缓存,工作速度相当于CPU速度的一半。Celeron以及更新的Pentium III芯片则分别具有128K和256K的在片二级缓存,能够在处理器全速下运行。 对于存放在速度较慢的二级缓存中的指令或数据,处理器往往需要等待2到4个时钟周期。为了充分利用计算资源,CPU可以在这段时间内查看和执行其它正在等候处理,但不需要使用额外数据的指令,从而提高整个系统的速度,把空闲时间降低到最低程度。
H. 银川北大青鸟分享PHP应用中常用的9大缓存技术
一、全页面静态化缓存也就是将页面全部生成html静态页面,用户访问时直接访问的静态页面,而不会去走php服务器解析的流程。
此种方式,在CMS系统中比较常见,比如dedecms;一种比较常用的实现方式是用输出缓存:Ob_start()******要运行的代码*******$content=Ob_get_contents();****将缓存内容写入html文件*****Ob_end_clean();二、数据缓存顾名思义,就是缓存数据的一种方式;比如,商城中的某个商品信息,当用商品id去请求时,就会得出包括店铺信息、商品信息等数据,此时就可以将这些数据缓存到一个php文件中,文件名包含商品id来建一个唯一标示;下一次有人想查看这个商品时,首先就直接调这个文件里面的信息,而不用再去数据库查询;其实缓存文件中缓存的就是一个php数组之类;Ecmall商城系统里面就用了这种方式;三、查询缓存其实这跟数据缓存是一个思路,就是根据查询语句来缓存;将查询得到的数据缓存在一个文件中,下次遇到相同的查询时,就直接先从这个文件里面调数据,不会再去查数据库;但此处的缓存文件名可能就需要以查询语句为基点来建立唯一标示;按时间变更进行缓存就是对于缓存文件您需要设一个有效时间,在这个有效时间内,相同的访问才会先取缓存文件的内容,但是超过设定的缓存时间,就需要重新从数据库中获取数据,并生产最新的缓存文件;比如,我将我们商城的首页就是设置2个小时更新一次。
四、页面部分缓存该种方式,是将一个页面中不经常变的部分进行静态缓存,而经常变化的块不缓存,最后组装在一起显示;可以使用类似于ob_get_contents的方式实现,也可以利用类似ESI之类的页面片段缓存策略,使其用来做动态页面中相对静态的片段部分的缓存。
该种方式可以用于如商城中的商品页;五、Opcode缓存首先php代码被解析为Tokens,然后再编译为Opcode码,最后执行Opcode码,返回结果;所以,对于相同的php文件,第一次运行时可以缓存其Opcode码,下次再执行这个页面时,直接会去找到缓存下的opcode码,直接执行最后一步,而不再需要中间的步骤了。
比较知名的是XCache、TurckMMCache、PHPAccelerator等。
六、按内容变更进行缓存这个也并非独立的缓存技术,需结合着用;就是当数据库内容被修改时,即刻更新缓存文件;比如,一个人流量很大的商城,商品很多,商品表必然比较大,这表的压力也比较重;我们就可以对商品显示页进行页面缓存;当商家在后台修改这个商品的信息时,点击保存,我们同时就更新缓存文件;那么,买家访问这个商品信息时,实际问的是一个静态页面,而不需要再去访问数据库;试想,如果对商品页不缓存,那么每次访问一个商品就要去数据库查一次,如果有10万人在线浏览商品,那服务器压力就大了;七、内存式缓存提到这个,可能大家想到的首先就是Memcached;memcached是高性能的分布式内存缓存服务器。
一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。
它就是将需要缓存的信息,缓存到系统内存中,需要获取信息时,直接到内存中取;比较常用的方式就是key_>value方式;connect($memcachehost,$memcacheport)ordie("Couldnotconnect");$memcache->set('key','缓存的内容');$get=$memcache->get($key);//获取信息?>八、apache缓存模块apache安装完以后,是不允许被cache的。
银川IT培训http://www.kmbdqn.cn/认为如果外接了cache或squid服务器要求进行web加速的话,就需要在htttpd.conf里进行设置,当然前提是在安装apache的时候要激活mod_cache的模块。
I. ☆前端优化:浏览器缓存技术介绍
在前端开发中,性能一直都是被大家所重视的一点,然而判断一个网站的性能最直观的就是看网页打开的速度。 其中提高网页反应速度的一个方式就是使用缓存 。缓存技术一直一来在WEB技术体系中扮演非常重要角色,是快速且有效地提升性能的手段。
一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。
所以,缓存技术是无数WEB开发从业人员在工作过程中不可避免的一大问题。 在产品开发的时候我们总是想办法避免缓存产生,而在产品发布之时又在想策略管理缓存提升网页的访问速度 。了解浏览器的缓存命中原理,是开发WEB应用的基础,本文着眼于此,学习浏览器缓存的相关知识,总结缓存避免和缓存管理的方法,结合具体的场景说明缓存的相关问题。希望能对有需要的人有所帮助。
在实际WEB开发过程中,缓存技术会涉及到不同层、不同端,比如:用户层、系统层、代理层、前端、后端、服务端等, 每一层的缓存目标都是一致的,就是尽快返回请求数据、减少延迟 ,但每层使用的技术实现是各有不同,面对不同层、不同端的优劣,选用不同的技术来提升系统响应效率。所以,我们首先看下各层的缓存都有哪些技术,都缓存哪些数据,从整体上,对WEB的缓存技术进行了解,如下图所示:
本篇文章重点讲的就是上面红色框部分缓存内容。
当浏览器请求一个网站的时候,会加载各种各样的资源,比如:HTML文档、图片、CSS和JS等文件。对于一些不经常变的内容,浏览器会将他们保存在本地的文件中,下次访问相同网站的时候,直接加载这些资源,加速访问。
那么如何知晓浏览器是读取了缓存还是直接请求服务器?如下图网站来做个示例:
第一次打开该网站后,如果再次刷新页面。会发现浏览器加载的众多资源中,有一部分size有具体数值,然而还有一部分请求,比如图片、css和js等文件并没有显示文件大小,而是显示了 from dis cache 或者 from memory cache 字样。这就说明了,该资源直接从本地硬盘或者浏览器内存读取,而并没有请求服务器。
浏览器启用缓存至少有两点显而易见的好处: (1)减少页面加载时间;(2)减少服务器负载;
浏览器是否使用缓存、缓存多久,是由服务器控制的 。准确来说,当浏览器请求一个网页(或者其他资源)时, 服务器发回的响应的“响应头”部分的某些字段指明了有关缓存的关键信息 。下面看下,HTTP报文中与缓存相关的首部字段:
根据上面四种类型的首部字段不同使用策略, 浏览器中缓存可分为强缓存和协商缓存 :
当浏览器对某个资源的请求命中了强缓存时, 返回的HTTP状态为200 ,在chrome的开发者工具的network里面 size会显示为from cache ,比如:京东的首页里就有很多静态资源配置了强缓存,用chrome打开几次,再用f12查看network,可以看到有不少请求就是从缓存中加载的:
Expires是HTTP 1.0提出的一个表示资源过期时间的header,它描述的是一个绝对时间,由服务器返回,用GMT格式的字符串表示 ,如:Expires:Thu, 31 Dec 2037 23:55:55 GMT,包含了Expires头标签的文件,就说明浏览器对于该文件缓存具有非常大的控制权。
例如,一个文件的Expires值是2020年的1月1日,那么就代表,在2020年1月1日之前,浏览器都可以直接使用该文件的本地缓存文件,而不必去服务器再次请求该文件,哪怕服务器文件发生了变化。
所以, Expires是优化中最理想的情况,因为它根本不会产生请求 ,所以后端也就无需考虑查询快慢。它的缓存原理,如下:
Expires是较老的强缓存管理header, 由于它是服务器返回的一个绝对时间 ,在服务器时间与客户端时间相差较大时,缓存管理容易出现问题, 比如:随意修改下客户端时间,就能影响缓存命中的结果 。所以在HTTP 1.1的时候,提出了一个新的header, 就是Cache-Control,这是一个相对时间,在配置缓存的时候,以秒为单位,用数值表示 ,如:Cache-Control:max-age=315360000,它的缓存原理是:
Cache-Control描述的是一个相对时间 ,在进行缓存命中的时候, 都是利用客户端时间进行判断 ,所以相比较Expires,Cache-Control的缓存管理更有效,安全一些。
这两个header可以只启用一个,也可以同时启用, 当response header中,Expires和Cache-Control同时存在时,Cache-Control优先级高于Expires :
此外,还可以为 Cache-Control 指定 public 或 private 标记。 如果使用 private,则表示该资源仅仅属于发出请求的最终用户,这将禁止中间服务器(如代理服务器)缓存此类资源 。对于包含用户个人信息的文件(如一个包含用户名的 HTML 文档),可以设置 private,一方面由于这些缓存对其他用户来说没有任何意义,另一方面用户可能不希望相关文件储存在不受信任的服务器上。需要指出的是,private 并不会使得缓存更加安全,它同样会传给中间服务器(如果网站对于传输的安全性要求很高,应该使用传输层安全措施)。 对于 public,则允许所有服务器缓存该资源 。通常情况下,对于所有人都可以访问的资源(例如网站的 logo、图片、脚本等), Cache-Control 默认设为 public 是合理的 。
当浏览器对某个资源的请求没有命中强缓存, 就会发一个请求到服务器,验证协商缓存是否命中,如果协商缓存命中,请求响应返回的http状态为304并且会显示一个Not Modified的字符串 ,比如你打开京东的首页,按f12打开开发者工具,再按f5刷新页面,查看network,可以看到有不少请求就是命中了协商缓存的:
查看单个请求的Response Header, 也能看到304的状态码和Not Modified的字符串,只要看到这个就可说明这个资源是命中了协商缓存,然后从客户端缓存中加载的 ,而不是服务器最新的资源:
【Last-Modified,If-Modified-Since】的控制缓存的原理,如下 :
【Last-Modified,If-Modified-Since】都是根据服务器时间返回的header,一般来说, 在没有调整服务器时间和篡改客户端缓存的情况下,这两个header配合起来管理协商缓存是非常可靠的,但是有时候也会服务器上资源其实有变化,但是最后修改时间却没有变化的情况 ,而这种问题又很不容易被定位出来,而当这种情况出现的时候,就会影响协商缓存的可靠性。 所以就有了另外一对header来管理协商缓存,这对header就是【ETag、If-None-Match】 。它们的缓存管理的方式是:
Etag和Last-Modified非常相似,都是用来判断一个参数,从而决定是否启用缓存。 但是ETag相对于Last-Modified也有其优势,可以更加准确的判断文件内容是否被修改 ,从而在实际操作中实用程度也更高。
协商缓存跟强缓存不一样,强缓存不发请求到服务器, 所以有时候资源更新了浏览器还不知道,但是协商缓存会发请求到服务器 ,所以资源是否更新,服务器肯定知道。大部分web服务器都默认开启协商缓存,而且是同时启用【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】,比如apache:
如果没有协商缓存,每个到服务器的请求,就都得返回资源内容,这样服务器的性能会极差。
【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】一般都是同时启用,这是为了处理Last-Modified不可靠的情况。有一种场景需要注意:
比如,京东页面的资源请求,返回的repsonse header就只有Last-Modified,没有ETag:
协商缓存需要配合强缓存使用,上面这个截图中,除了Last-Modified这个header,还有强缓存的相关header, 因为如果不启用强缓存的话,协商缓存根本没有意义 。
如果资源已经被浏览器缓存下来,在缓存失效之前,再次请求时,默认会先检查是否命中强缓存,如果强缓存命中则直接读取缓存,如果强缓存没有命中则发请求到服务器检查是否命中协商缓存,如果协商缓存命中,则告诉浏览器还是可以从缓存读取,否则才从服务器返回最新的资源。其浏览器判断缓存的详细流程图,如下:
J. 缓存的技术指标
CPU产品中,一级缓存的容量基本在4kb到64kb之间,二级缓存的容量则分为128kb、256kb、512kb、1mb、2mb等。一级缓存容量各产品之间相差不大,而二级缓存容量则是提高cpu性能的关键。二级缓存容量的提升是由cpu制造工艺所决定的,容量增大必然导致cpu内部晶体管数的增加,要在有限的cpu面积上集成更大的缓存,对制造工艺的要求也就越高
缓存(cache)大小是CPU的重要指标之一,其结构与大小对CPU速率的影响非常大。简单地讲,缓存就是用来存储一些常用或即将用到的数据或指令,当需要这些数据或指令的时候直接从缓存中读取,这样比到内存甚至硬盘中读取要快得多,能够大幅度提升cpu的处理速率。所谓处理器缓存,通常指的是二级高速缓存,或外部高速缓存。即高速缓冲存储器,是位于CPU和主存储器dram(dynamic ram)之间的规模较小的但速率很高的存储器,通常由sram(静态随机存储器)组成。用来存放那些被cpu频繁使用的数据,以便使cpu不必依赖于速率较慢的dram(动态随机存储器)。l2高速缓存一直都属于速率极快而价格也相当昂贵的一类内存,称为sram(静态ram),sram(static ram)是静态存储器的英文缩写。由于sram采用了与制作cpu相同的半导体工艺,因此与动态存储器dram比较,sram的存取速率快,但体积较大,价格很高。
处理器缓存的基本思想是用少量的sram作为cpu与dram存储系统之间的缓冲区,即cache系统。80486以及更高档微处理器的一个显着特点是处理器芯片内集成了sram作为cache,由于这些cache装在芯片内,因此称为片内cache。486芯片内cache的容量通常为8k。高档芯片如pentium为16kb,power pc可达32kb。pentium微处理器进一步改进片内cache,采用数据和双通道cache技术,相对而言,片内cache的容量不大,但是非常灵活、方便,极大地提高了微处理器的性能。片内cache也称为一级cache。由于486,586等高档处理器的时钟频率很高,一旦出现一级cache未命中的情况,性能将明显恶化。在这种情况下采用的办法是在处理器芯片之外再加cache,称为二级cache。二级cache实际上是cpu和主存之间的真正缓冲。由于系统板上的响应时间远低于cpu的速率,没有二级cache就不可能达到486,586等高档处理器的理想速率。二级cache的容量通常应比一级cache大一个数量级以上。在系统设置中,常要求用户确定二级cache是否安装及尺寸大小等。二级cache的大小一般为128kb、256kb或512kb。在486以上档次的微机中,普遍采用256kb或512kb同步cache。所谓同步是指cache和cpu采用了相同的时钟周期,以相同的速率同步工作。相对于异步cache,性能可提高30%以上。pc及其服务器系统的发展趋势之一是cpu主频越做越高,系统架构越做越先进,而主存dram的结构和存取时间改进较慢。因此,缓存(cache)技术愈显重要,在pc系统中cache越做越大。广大用户已把cache做为评价和选购pc系统的一个重要指标。