① spring mvc 怎么设计缓存
用于提供如浏览器缓存控制、是否必须有session开启、支持的请求方法类型(GET、POST等)等,该类主要有如下属性:
Set<String> supportedMethods:设置支持的请求方法类型,默认支持“GET”、“POST”、“HEAD”,如果我们想支持“PUT”,则可以加入该集合“PUT”。
boolean requireSession = false:是否当前请求必须有session,如果此属性为true,但当前请求没有打开session将抛出HttpSessionRequiredException异常;
boolean useExpiresHeader = true:是否使用HTTP1.0协议过期响应头:如果true则会在响应头添加:“Expires:”;需要配合cacheSeconds使用;
boolean useCacheControlHeader = true:是否使用HTTP1.1协议的缓存控制响应头,如果true则会在响应头添加;需要配合cacheSeconds使用;
boolean useCacheControlNoStore = true:是否使用HTTP 1.1协议的缓存控制响应头,如果true则会在响应头添加;需要配合cacheSeconds使用;
private int cacheSeconds = -1:缓存过期时间,正数表示需要缓存,负数表示不做任何事情(也就是说保留上次的缓存设置),
1、cacheSeconds =0时,则将设置如下响应头数据:
Pragma:no-cache // HTTP 1.0的不缓存响应头
Expires:1L // useExpiresHeader=true时,HTTP 1.0
Cache-Control :no-cache // useCacheControlHeader=true时,HTTP 1.1
Cache-Control :no-store // useCacheControlNoStore=true时,该设置是防止Firefox缓存
2、cacheSeconds>0时,则将设置如下响应头数据:
Expires:System.currentTimeMillis() + cacheSeconds * 1000L // useExpiresHeader=true时,HTTP 1.0
Cache-Control :max-age=cacheSeconds // useCacheControlHeader=true时,HTTP 1.1
3、cacheSeconds<0时,则什么都不设置,即保留上次的缓存设置。
此处简单说一下以上响应头的作用,缓存控制已超出本书内容:
HTTP1.0缓存控制响应头
Pragma:no-cache:表示防止客户端缓存,需要强制从服务器获取最新的数据;
Expires:HTTP1.0响应头,本地副本缓存过期时间,如果客户端发现缓存文件没有过期则不发送请求,HTTP的日期时间必须是格林威治时间(GMT),如“Expires:Wed, 14 Mar 2012 09:38:32 GMT”;
HTTP1.1缓存控制响应头
Cache-Control :no-cache 强制客户端每次请求获取服务器的最新版本,不经过本地缓存的副本验证;
Cache-Control :no-store 强制客户端不保存请求的副本,该设置是防止Firefox缓存
Cache-Control:max-age=[秒] 客户端副本缓存的最长时间,类似于HTTP1.0的Expires,只是此处是基于请求的相对时间间隔来计算,而非绝对时间。
还有相关缓存控制机制如Last-Modified(最后修改时间验证,客户端的上一次请求时间 在 服务器的最后修改时间 之后,说明服务器数据没有发生变化 返回304状态码)、ETag(没有变化时不重新下载数据,返回304)。
该抽象类默认被AbstractController和WebContentInterceptor继承。
② php 缓存如何设计
ob_get_contents, ob_end_clean从实现上应该是ob_get_clean的分解步骤。后者因为从c代码层面的整合,在仅单次执行时,速度上应该有微量的优势。因为优势远比网络IO的延迟要小,几乎可以忽略吧。
echo ob_get_contents应该也一般是用于首次生成模板缓存。是内存操作。
include用于直接显示。是文件操作。
显示模板可以用后者,做缓存所节约的时间主要是处理计算和各媒介之间的IO上的,根据自己的应用和自己的设备环境在慢的、瓶颈部分作出调整,是灵活的。没有定式。
③ redis的一个缓存问题,怎样才能做到设计最优
网页缓存会对下一次打开这个网页的速度有所帮助。 IE网页缓存文件是可以删除的,那只是你浏览过的网页的图片文字等等的一些东西在,删除下,这样对你以后浏览这个网页的时候,就不需要再次从服务器下载图片等数据,
④ 云南北大青鸟设计培训告诉你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的模块。此哪圆
⑤ php不使用第三方工具,如何设计缓存
结论:可自行设计,或使用内置APCu缓存。
1 - 第三方缓存
常用的第三方缓存工具,一般是指redis,memcached,以及云服务商提供的缓存服务。基本不脱离此二类范围。
用法非常直观,我们不做深入的介绍了。可在官方手册内查看。
4 - 写在最后
本文简要说明了PHP内缓存数据可能使用的方法。我们推荐使用成熟的类库或扩展,不要重复造轮子。
⑥ APP中缓存、加载与刷新机制设计【转载】
1、为什么要加缓存?
场景一:【等待】,在向服务器请求新的数据时。我们让用户看到什么?第一种是漂亮的等待加载页面;第二种是缓存的内容。对于第二种,用户可以对页面进行操作,等待新数据时可以查看旧数据,更具有“可操作性”与“可用性”,从而减轻了从服务器获取数据这一动作的大小和时间长短,增强了用户体验。另一方面,如果内容更新的间隔较长或者用户刷新的间隔较短,在没有缓存的情况下,很多数据我们会多次重复的向服务器获取,增加了成本。
场景二:【结果】没有联网,或者在地铁上网络太差无法加载数据时,如果留给用户一个空白页面,实在是感觉有点不负责任啊。并且很多功能在没有联网的情况下也有使用的可能性,比如:APP中的通讯录,查看一些聊天记录,通知信息,文章列表等。因为用户打开APP不一定是要看新信息,说不定是回顾老信息(或许老信息里也有用户之前没看的),所以恰当的缓存可以满足更多的用户场景。
场景三:【金钱】有一天,一个用户发现自己装了某个APP后流量用的特别快,Ta可能永远将这个APP打入冷宫了,而增加缓存正是节省流量的一个方法。虽然节省的不多或者用户也察觉不到,但是作为一个有态度的产品经理,应该多做一些思考。
2、什么是缓存?
缓存可分为如下几类:
(1)app缓存。
(2)固定缓存。
(3)可手动清理的缓存。
(4)不可手动清理的缓存。
(5)临时缓存。
其中,临时缓存常用于一个功能页面内,保存各栏目的缓存。同一个功能里会把子功能分为多个栏目进行划分,每个标签栏目下的内容在本次使用中都可保存为临时缓存,在该功能里切换栏目,不需要重新加载数据,使用缓存显示。
对于用户来说,使用时达到了无缝切换浏览,对于服务器来说,在短时间内数据很少会有更新,所以在一般情况下能满足用户的正常需求,并达到体验优秀。
临时缓存的清理机制是:退出该功能模块就清除之前的缓存。也就是说下次进入该功能模块,需要重新获取一次数据。
很多时候我们都会用到临时缓存,因为那些信息真的不是那么重要,而且不需要经常反复查看,那对于那些我们经常使用而且经常需要反复查看的信息,马海祥建议采取固定缓存,保存在本地,方便下次翻阅时不需要再一次向服务器请求数据了。
对于固定缓存又会细分为可手动清理的缓存和不可手动清理的缓存。
第一种是我们最常见的缓存,几乎所有产品都采用这种缓存方式。平时用户浏览文章、图集加载的数据就以这种形式缓存在本地,下次看回这篇文章、图集时就不需要加载了。用户也可以手动把这些缓存清理了,释放空间。
而对于某些特殊场景,例如一些相对固定的数据,我们不愿意一开始就打包进App里,这样会占太大容量,造成产品包很大,也不愿意每次进入页面都向服务器加载这些信息,那怎么办?建议的解决方法就是我们可以只加载一次就永远存在本地了,这样安装包也不会大,以后也不用加载了。
3、如何清理缓存?
一般App都会在“设置”里提供一个清理缓存的功能,一键把空间释放。除此之外,App最好要设计自动清理机制,可以通过两个维度来设计这个机制。
(1)、时间
通过设定一个固定的时间,或者根据用户使用周期灵活设定时间来清理缓存。每个产品的场景不一,用户使用频率不一,设定这个机制的时候就需要结合实际情况考虑了。
(2)、容量
一般是设定一个容量上限,采用堆栈的设计原理进行缓存清理,溢出堆栈的旧数据将自动清除。
1、页面加载
方案1:单页面整体加载
这种加载比较简单,一般运用在页面内容比较单一的情况下,所以直接一次性加载完所有数据后再显示内容。其单页面加载失败的状态相对来说也比较好处理。
方案2:单页面分块加载
这种方案的特点是,能让用户逐步看到内容,在这个渐进的过程中降低用户的焦虑心理。
其中又可以分为,模块间有关联性的,先加载父内容,再加载子内容。如优酷,先把栏目加载出来,再加载各栏目的内容。
模块间没有绝对关联性的,可独自加载各自模块内容,根据请求的速度不同分别显示。这样处理有一定几率让用户在没完全刷出数据的情况下就能找到自己需要的功能,如大众点评、淘宝客户端等。
框架固定,内容更新的,可先把框架显示出来,再把各模块的数据各自加载显示,如各种iOS自带应用。
这种分模块加载的需要特别注意加载失败的状态,毕竟每个模块都提示加载失败,点击重试是很挫的一件事,可以根据信息的优先级来决定哪些数据失败了采用默认状态,哪些数据采用失败提示。
方案3:跨页面加载
父页面&子页面 or 同一app内,页面间字段可以复用的,在加载子页面时不需要重新加载新数据。
方案4:预加载
这种加载方式的特点是,在加载一个页面内容的同时,预测用户的下一步行为,并为他下一步需要使用的页面加载内容,使得他在下一步的操作中能立刻获取信息而不需要加载等待。
预加载提供给用户无缝的产品使用体验,使得用户在使用产品的过程中更直接流畅,没有被打断的感觉。
具体的例子有:
在浏览图集的时候,当看到第一张的图片时,就自动后台加载第二第三第四张图片,用户浏览完第一张图片切换到第二张时就不会有加载等待的过程。
在浏览新闻列表时,就把每篇新闻的内容在后台进行预加载,用户选择看某篇新闻时,能立刻阅读到内容。
但是这种方案也需要面临很多的问题,马海祥觉得最直接的就是流量问题,因为会自动跑掉很多用户可能根本用不上的数据流量,所以,一般情况下马海祥建议可以设定在wifi环境才采用这种加载模式。又或者设定加载规则,只把主要内容预加载,而部分次要内容可以在用户真的用到的时候才加载,例如预加载新闻正文的情况,可以只加载文本信息,图片信息等到用户进入内页才加载。这种预加载与分块加载结合的方式也普遍运用在各个场景。
另外,预加载也需要时间的,他只是不在客户端显示给用户,默默在后台运作而已,需要特殊考虑未加载完用户就使用到那些信息的情况,所以在做预加载设计时需要同时考虑另一种适合该情况的普通加载方式。
预加载需要根据具体的场景来进行设计,设定好信息优先级,综合考虑各种类型信息的具体大小流量,整体考虑预加载的方式,这些都是需要经过精心分析思考的。
随着网络环境的发展,预加载将成为以后产品普遍的加载方式,他提供给用户的无缝使用体验**地提升了产品的可用性。
2、操作加载
除了页面的信息需要加载,页面内的操作也是需要通过给服务器发送请求记录的。
方案1:加载层
进行一个操作后,弹出模态的提示层,告知用户正在加载。采用模态的提示主要是防止用户在该过程中进行其他操作,导致当前加载出错。由于采用模态的提示,并且有可能因为网络原因导致长时间处于加载状态,建议提供一个“关闭”的操作,中止本次加载,恢复App可用状态。加载失败时可在当前浮层变换为失败提示。模态提示层是最稳妥的方式,但他会使用户在使用过程中有打断的感觉。
方案2:控件自身加载状态
这种方式是把操作加载的状态与控件的样式结合起来了,对某个控件进行操作后,控件变换为加载状态,此时控件不能重复操作。由于这种加载方式是控件的自身状态,不影响其他操作,所以用户也可以对页面进行其他操作,可能会导致同时有多个请求的情况,增加了加载失败的风险,这也算是这种方式的弊端,不过这种极端情况很少出现。请求失败后,可配合Toast提示告知用户失败的原因。
方案3:后台加载
用户在操作后,客户端立刻反馈操作成功,然后把请求放到后台与服务器交互,这一过程用户不需要了解,不需要等待,在正常情况**验是非常棒的。
但是在极端情况下会出现一些莫名其妙的状况,由于是后台记录请求并与服务器交互,所以实际请求是否成功客户端是不说明的,全部以操作成功来显示,这就会导致用户误以为操作成功了,但实际上下次来看发现没有成功。
所以,这种加载方式是需要根据具体使用场景来权衡使用的,对于一些重要的操作,建议还是使用模态的方式加载,对于一些小操作,如点赞、订阅、关注,可采用后台加载的方式。
3、下一页加载还是当前也加载
用户进入首页,正式迈出体验的第一步,接下来迎接的就是基于用户目标的界面间跳转。完成界面的跳转,会有各种加载策略,但无论形式如何,我们都可以将其归为两大类:“下一页加载”、“当前页加载”。
(1)“下一页加载”满足了用户提前窥视的需求
我们把页面看成“点”,页面流是连接这些点的“线”,我们以“用户想买一条牛仔裤”这一场景作为案例做了简单的眼动研究,从应用启动到商品浏览再到商品确定最后进入下单页,用户所呈现的瞳孔梯次增大,即E>D>C>B>A,为了解释这一现象,通过与被试交流,我们发现相比于各种浏览,用户更期待看到他们想看到的东西。因此此时的”下一页加载“正好,满足了用户提前窥视的需求。
(2) Wait!I Need Think Think
我们以同样的方式又对“使用支付宝对手机充值”这一场景做了研究,从开始支付到二次确认支付,用户所呈现的瞳孔都比较大,即A与B近似相等,通过访谈,我们发现与“递增体验流”不同的是,当用户遇到判断逻辑的界面时,用户并非急于想看下一页面到底包含怎样的内容,而是非0即1的验证心态,即我的操作效成功了吗?因此在判断逻辑界面中,用户的内容窥视需求并不强,当然也没什么内容,要么仅是一个小小的Toast,再大一点就是一个简单的信息反馈界面(意味着“下一页加载”在这里就是个鸡肋),用户反而对非0即1的验证需求较为强烈,其中还伴随着等待结果过程中的紧张感、激动感,因此界面通过 当前页加载 表明系统正在努力地处理用户交代的指令**了用户的紧张感、激动感,直到结果显现——“处理成功”,完成了非0即1验证的满足感。
4、先加载还是先展示
当需加载的是功能时,可以先展示再加载,当需加载的是内容时,则反过来。
淘宝
打开APP的第一个页面是功能,所以先展示再加载的:
随便点击一个模块(不要点菜单),下面要展示的将要是内容(商品),所以是先加载再展示的,没有加载完都不展示:
京东
同样的,功能模块先展示后加载:
内容先加载,没加载完不展示:
两种方式各有利弊:
先展示,后加载:
优点:给用户0等待的错觉
缺点:当前数据有可能是错的,而且得等用户操作到最后一步才会发现
先加载,后展示:
优点:保证数据的质量和准确
缺点:网络不好时,造成等待
显然,功能模块对于一个产品来说是既有固定的,在短时间内几乎不会更新,所以这种数据出现错误或与当前状态不同的几率小得多,因此,可以使用先展示后加载的方式。
另一方面,内容(特别是商品数据)是最容易产生变动的,为了保证每一个消费者看到的数据都是最真实,最准确的,所以务必要先加载再展示。
1、空白页面刷新失败有提示
现在的应用都标榜以内容为中心,所以都会极力避免空白页面的出现。对于大部分的应用,最好的方法就是使用缓存,进入页面之后,先显示之前的缓存,然后再进行内容的刷新。其次,消灭空白页面的第二种方法就是提供系统推荐项进行替代。但是对于一些页面,页面内容跟用户的使用状态关系密切,无法避免会出现空白页面,这时候会使用一些引导类的提示,使得页面变得更加丰富,同时可以促进用户产生内容。
但是一些资讯类应用,比如读读日报,打开默认是空白页面,然后再加载内容(我不是很明白这种设定)。其他一些应用,比如:豆瓣一刻和MONO,每天第一次进入应用的时候也会出现空白页面。我猜想第二类应用的展示方式的原因是这样的。他们的内容**都是严格以天为单位的,每天固定时段**精选内容。他们会希望你每天只看并且看完当天的东西,所以一旦到了第二天,昨天的内容就是累赘了。所以每天第一次进入应用的时候会出现空白页面,象征着每天都是从新开始。此时就会对应一个“空白刷新”逻辑。
空白刷新对应的场景是这样子的:用户想要刷新出内容,并且用户知道这里可以刷出新内容,但是没有刷新成功,这时候需要给用户一个交待。所以需要提示用户。同时,提示完用户之后需要给用户一个解决方法,这就是“点击后重试”。
2、缓存页面刷新失败无提示
常见的应用比如知乎、网易新闻、好奇心日报、微信朋友圈等,这些应用都会采用缓存的形式,打开之后显示的是缓存内容,然后系统会给服务器发送请求,如果有内容更新的话就会自动更新一次内容,更新之后的内容直接覆盖当前的内容。更新失败之后是没有提示的。但是有一些应用,比如有道词典、企鹅FM、网易云音乐等,他们更新失败之后是有提示的。
我觉得这两种应用的区分点在于
应用的使用频率;
内容的时间连续性;
界面之间的关系紧密度。
比如说网易新闻,作为一个打发时间的工具,每天使用频率就会比较高,所以用户进来之后是想看看有没有更新。其次,网易新闻的内容是连续不断更新的,所以用户会知道当前显示的内容是我看看过并且处理过的。最后,新闻列表页面显示的是摘要,用户可以通过摘要快速进行判断是否要进入详情页,摘要有助于帮助用户回忆上一次的使用场景。
所以这就对应着一个这样的场景:用户只是想看看有没有更新,所以他们已经做好了“没有新内容”的心理预期,所以即使是更新不了内容,用户也不会想太多。反倒是,如果进行了错误提示,用户可能会有一种挫败感。因为他知道现在有内容,只是因为网络的原因而没有更新,他要进行的任务受到了外界因素的阻碍,由此产生一种细微的挫败感。
3、缓存页面刷新失败有提示
另一类应用,使用频率没那么高,或者内容不具备时间连续性的,又或者说当前界面无法唤起用户上一次的使用场景。那么就有必要进行率先你失败提示了。
比如说企鹅FM,音频类的应用注定使用不会那么频繁,因为通过视觉接收的信息会比通过听觉接收的信息更快更多,同时音频类对环境的要求较高(比如用耳机时要求环境不那么嘈杂,外放时要求在私人场所)。其次,此类应用都是实时推荐的,不存在时间连续性的问题,用户无法通过时间来判断内容是否被阅读过。再者,标题也无法帮你快速做出判断,你还是要进去听过才知道内容是什么。最后如果不提醒,用户进入到详情页再收到提醒,就会觉得应用浪费了用户的时间。所以,对于此类内容,刷新失败是有必要进行提醒的。
⑦ Fikker的缓存怎么设计的
他们的白皮书上写的很详细。很长~~ 我给你截一段说明。
2.1. 缓存说明
在 Fikker 系统中,缓存分为智能缓存,强制缓存,拒绝缓存。加速缓存的页面(html,
asp,aspx,php,jsp,js,css 等)被 gzip 压缩后以平衡二叉树的索引结构存放在内
存中,不对硬盘进行任何读写(日志除外)。当加速缓存中的页面被访问命中以后,
立即通过压缩传输方式返回给浏览器。以上处理方式有如下好处:(1)、不读写硬
盘,通过内存进行数据交换会极大的提高页面相应速度;(2)、将页面数据经过 gzip
压缩后存储,即减少了对内存空间的需求,也会极大的减少数据传输量,从整体上
提高响应速度和传输效率。
⑧ 关于一级缓存和二级缓存,以及nvidia!!!!
nvidia是一个公司
而高速缓存分为一级缓存(即L1 Cache)和二级缓存(即L2Cache)。CPU在运行时首先从一级缓存读取数据,然后从二级缓存读取数据,然后从内存和虚拟内存读取数据,因此高速缓存的容量和速度直接影响到CPU的工作性能。 一级缓存都内置在CPU内部并与CPU同速运行,可以有效的提高CPU的运行效率。一级缓存越大,CPU的运行效率越高,但受到CPU内部结构的限制,一级缓存的容量都很小。 二级缓存对CPU运行效率的影响也很大,现在的二级缓存一般都集成在中,但有分为芯片内部和外部两种,集成在芯片内部的二级缓存与CPU同频率二级缓存(即全速二级缓存),而集成在芯片外部的二级缓存的运行频率 是CPU的运行频率的一半(即半速二级缓存),因此运行效率较低。 但是一级缓存和二级缓存的大,它究竟有多少好处呢?你得告诉我们经销商,实际上你得用最普通的话跟他讲。所以我们给他们打个比方,说这个就好比你开汽车的时候,后备箱是整个的一级缓存,假如说扶手里面有一个小箱子,那是你的二级缓存。二级缓存大好在哪里呢?就是你随时开车的时候,随时在里面都可以取东西了。假如你二级缓存小的话,你还得把车停下来,到后备箱里取东西。
首先我们来简单了解一下一级缓存。目前所有主流处理器大都具有一级缓存和二级缓存,少数高端处理器还集成了三级缓存。其中,一级缓存可分为一级指令缓存和一级数据缓存。一级指令缓存用于暂时存储并向CPU递送各类运算指令;一级数据缓存用于暂时存储并向CPU递送运算所需数据,这就是一级缓存的作用(如果大家对上述文字理解困难的话,可参照下图所示)。
那么,二级缓存的作用又是什么呢?简单地说,二级缓存就是一级缓存的缓冲器:一级缓存制造成本很高因此它的容量有限,二级缓存的作用就是存储那些CPU处理时需要用到、一级缓存又无法存储的数据。同样道理,三级缓存和内存可以看作是二级缓存的缓冲器,它们的容量递增,但单位制造成本却递减。需要注意的是,无论是二级缓存、三级缓存还是内存都不能存储处理器操作的原始指令,这些指令只能存储在CPU的一级指令缓存中,而余下的二级缓存、三级缓存和内存仅用于存储CPU所需数据。
根据工作原理的不同,目前主流处理器所采用的一级数据缓存又可以分为实数据读写缓存和数据代码指令追踪缓存2种,它们分别被AMD和Intel所采用。不同的一级数据缓存设计对于二级缓存容量的需求也各不相同,下面让我们简单了解一下这两种一级数据缓存设计的不同之处。
一、AMD一级数据缓存设计
AMD采用的一级缓存设计属于传统的“实数据读写缓存”设计。基于该架构的一级数据缓存主要用于存储CPU最先读取的数据;而更多的读取数据则分别存储在二级缓存和系统内存当中。做个简单的假设,假如处理器需要读取“AMD ATHLON 64 3000+ IS GOOD”这一串数据(不记空格),那么首先要被读取的“AMDATHL”将被存储在一级数据缓存中,而余下的“ON643000+ISGOOD”则被分别存储在二级缓存和系统内存当中(如下图所示)。
需要注意的是,以上假设只是对AMD处理器一级数据缓存的一个抽象描述,一级数据缓存和二级缓存所能存储的数据长度完全由缓存容量的大小决定,而绝非以上假设中的几个字节。“实数据读写缓存”的优点是数据读取直接快速,但这也需要一级数据缓存具有一定的容量,增加了处理器的制造难度(一级数据缓存的单位制造成本较二级缓存高)。
二、Intel一级数据缓存设计
自P4时代开始,Intel开始采用全新的“数据代码指令追踪缓存”设计。基于这种架构的一级数据缓存不再存储实际的数据,而是存储这些数据在二级缓存中的指令代码(即数据在二级缓存中存储的起始地址)。假设处理器需要读取“INTEL P4 IS GOOD”这一串数据(不记空格),那么所有数据将被存储在二级缓存中,而一级数据代码指令追踪缓存需要存储的仅仅是上述数据的起始地址(如下图所示)。
由于一级数据缓存不再存储实际数据,因此“数据代码指令追踪缓存”设计能够极大地降CPU对一级数据缓存容量的要求,降低处理器的生产难度。但这种设计的弊端在于数据读取效率较“实数据读写缓存设计”低,而且对二级缓存容量的依赖性非常大。
在了解了一级缓存、二级缓存的大致作用及其分类以后,下面我们来回答以下硬件一菜鸟网友提出的问题。
从理论上讲,二级缓存越大处理器的性能越好,但这并不是说二级缓存容量加倍就能够处理器带来成倍的性能增长。目前CPU处理的绝大部分数据的大小都在0-256KB之间,小部分数据的大小在256KB-512KB之间,只有极少数数据的大小超过512KB。所以只要处理器可用的一级、二级缓存容量达到256KB以上,那就能够应付正常的应用;512KB容量的二级缓存已经足够满足绝大多数应用的需求。
这其中,对于采用“实数据读写缓存”设计的AMD Athlon 64、Sempron处理器而言,由于它们已经具备了64KB一级指令缓存和64KB一级数据缓存,只要处理器的二级缓存容量大于等于128KB就能够存储足够的数据和指令,因此它们对二级缓存的依赖性并不大。这就是为什么主频同为1.8GHz的Socket 754 Sempron 3000+(128KB二级缓存)、Sempron 3100+(256KB二级缓存)以及Athlon 64 2800+(512KB二级缓存)在大多数评测中性能非常接近的主要原因。所以对于普通用户而言754 Sempron 2600+是值得考虑的。
反观Intel目前主推的P4、赛扬系列处理器,它们都采用了“数据代码指令追踪缓存”架构,其中Prescott内核的一级缓存中只包含了12KB一级指令缓存和16KB一级数据缓存,而Northwood内核更是只有12KB一级指令缓存和8KB一级数据缓存。所以P4、赛扬系列处理器对二级缓存的依赖性是非常大的,赛扬D 320(256KB二级缓存)与赛扬 2.4GHz(128KB二级缓存)性能上的巨大差距就很好地证明了这一点;而赛扬D和P4 E处理器之间的性能差距同样十分明显。
最后,如果您是狂热的游戏发烧友或者从事多媒体制作的专业用户,那么具有1MB二级缓存的P4处理器和具有512KB/1MB二级缓存的Athlon 64处理器才是您理想的选择。因为在高负荷的运算下,CPU的一级缓存和二级缓存近乎“爆满”,在这个时候大容量的二级缓存能够为处理器带来5%-10%左右的性能提升,这对于那些要求苛刻的用户来说是完全有必要的。
⑨ 只用PHP,如何设计一套缓存系统
既然都是文件存储,那你这样还不如直接用Mysql做一个缓存表。
而且本身mysql也自己实现了一套查询缓存~