缓存
缓存(Cache memory)是硬盘控制器上的一块内存芯片,具有极快的存取速度,它是硬盘内部存储和外界接口之间的缓冲器。由于硬盘的内部数据传输速度和外界介面传输速度不同,缓存在其中起到一个缓冲的作用。缓存的大小与速度是直接关系到硬盘的传输速度的重要因素,能够大幅度地提高硬盘整体性能。当硬盘存取零碎数据时需要不断地在硬盘与内存之间交换数据,有大缓存,则可以将那些零碎数据暂存在缓存中,减小外系统的负荷,也提高了数据的传输速度。
基本简介[ ]
缓存是指可以进行高速数据交换的存储器,它先于内存与CPU交换数据,因此速度很快。L1 Cache(一级缓存)是CPU第一层高速缓存。内置的L1高速缓存的容量和结构对CPU的性能影响较大,不过高速缓冲存储器均由静态RAM组成,结构较复杂,在CPU管芯面积不能太大的情况下,L1级高速缓存的容量不可能做得太大。一般L1缓存的容量通常在32—256KB。L2 Cache(二级缓存)是CPU的第二层高速缓存,分内部和外部两种芯片。内部的芯片二级缓存运行速度与主频相同,而外部的二级缓存则只有主频的一半。L2高速缓存容量也会影响CPU的性能,原则是越大越好,普通台式机CPU的L2缓存一般为128KB到2MB或者更高,笔记本、服务器和工作站上用CPU的L2高速缓存最高可达1MB-3MB。
缓存只是内存中少部分数据的复制品,所以CPU到缓存中寻找数据时,也会出现找不到的情况(因为这些数据没有从内存复制到缓存中去),这时CPU还是会到内存中去找数据,这样系统的速度就慢下来了,不过CPU会把这些数据复制到缓存中去,以便下一次不要再到内存中去取。随着时间的变化,被访问得最频繁的数据不是一成不变的,也就是说,刚才还不频繁的数据,此时已经需要被频繁的访问,刚才还是最频繁的数据,又不频繁了,所以说缓存中的数据要经常按照一定的算法来更换,这样才能保证缓存中的数据是被访问最频繁的。
工作原理[ ]
缓存的工作原理是当CPU要读取一个数据时,首先从缓存中查找,找到就立即读取并送给CPU处理;没有找到,就用相对慢的速度从内存中读取并送给CPU处理,同时把这个数据所在的数据块调入缓存中,可以使得以后对整块数据的读取都从缓存中进行,不必再调用内存。正是这样的读取机制使CPU读取缓存的命中率非常高(大多数CPU可达90%左右),也就是说CPU下一次要读取的数据90%都在缓存中,只有大约10%需要从内存读取。这大大节省了CPU直接读取内存的时间,也使CPU读取数据时基本无需等待。总的来说,CPU读取数据的顺序是先缓存后内存。
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叫二级缓存。
Web 应用系统存在哪些速度差异?[ ]
- 读取文件系统 ? 读取磁盘
- 读取数据库内存 ? 读取文件系统
- 读取应用内存 ? 访问数据库服务器
- 读取静态文件 ? 访问应用服务器
- 读取浏览器缓存 ? 访问网站
缓存技术分类[ ]
- 操作系统磁盘缓存 ? 减少磁盘机械操作
- 数据库缓存 ? 减少文件系统 I/O
- 应用程序缓存 ? 减少对数据库的查询
- 客户端浏览器缓存 ? 减少对网站的访问
PHP缓存技术[ ]
WEB程序获取信息的方式主要是查询数据库,当数据库不是很大的情况下不会有太大的问题.然而,随着网站的发展,数据库呈几何级数的方式增长的时候,就会出现瓶颈.于是PHP缓存技术诞生了。.PHP缓存技术工作时,当程序查询数据的时候,会把相应的结果序列化后保存到文件中,以后同样的查询语句就可以不用直接查询数据库,而是从缓存文件中获得。这一改进使得程序运行速度得以大幅度提升.
- 目前应用PHP缓存技术比较流行的方法主要是Adodb+Smarty这样的黄金搭档.
- PHP缓存技术工作原理
- 首先看看adodb提供的数据缓存功能:
- <?php
- include('adodb.inc.php');load code common to ADOdb
- $ADODB_CACHE_DIR = '/usr/ADODB_cache';
- $conn = &ADONewConnection('mysql');create a connection
- $conn->PConnect(' ','userid',,'agora');connect to MySQL, agora db
- $sql = 'select CustomerName, CustomerID from customers';
- $rs = $conn->CacheExecute(15,$sql);
- ?> 如上,每次查询数据的时候,会把相应的结果序列化后保存到文件中,以后同样的查询语句就可以不用直接查询数据库,而是从缓存文件中获得。
- 再来看看Smarty提供的页面缓存功能:
- <?php 1<?php
- require('Smarty.class.php');
- $smarty = new Smarty;
- $smarty->caching = true;
- if(!$smarty->is_cached('index.tpl')) {
- // No cache available, do variable assignments here.
- $contents = get_database_contents();
- $smarty->assign($contents);
- }
- $smarty->display('index.tpl');
- ?>
如上,每次访问页面的时候,都会先检测相应的缓存是否存在,如果不存在,就连接数据库,得到数据,完成模板变量的赋值,显示页面,同时生成缓存文件,这样下次访问的时候缓存文件就发挥作用了,而不会再执行if块的数据查询语句了。当然,在实际使用中会有很多东西要考虑,比如,有效期的设置,缓存组的设置等等,具体可以查看Smarty手册中有关缓存(caching)的相关章节。
以上两个PHP流行组件缓存方式的侧重点是不同的,对于Adodb的缓存而言,它缓存的是数据,对于Smarty的缓存而言,它缓存的是页面。其他提供缓存功能的组件还有很多(如:PEAR::Cache_Lite等等),实际编程中使用哪个方案要具体情况具体分析,也可能会综合使用。
使用这些组件内置的缓存方案有一个很明显的好处是它们的实现对客户端而言都很透明。只要进行必要的设置(如:缓存时间,缓存目录等等)就可以了,而不用过多考虑实现缓存的细节问题,系统会根据设置自动管理缓存。但是其缺点也同样明显,因为每次请求仍然要用PHP解析一遍,效率和纯静态相比还是大打折扣,在大的PV面前还是不能满足要求,在这种情况下,仅仅做动态缓存就不够了,必须实现静态缓存。
PHP,一门最近几年兴起的web设计脚本语言,由于它的强大和可伸缩性,近几年来得到长足的发展,php相比传统的asp网站,在速度上有绝对的优势,想mssql转6万条数据php如需要40秒,asp不下2分钟.但是,由于网站的数据越来越多,我们渴求能更快速的调用数据,不必要每次都从数据库调,我们可以从其他的地方,比方一个文件,或者某个内存地址,这就是php的缓存技术,也就是Cache技术.
内容加载[ ]
在使用缓存数据前,必须将数据加载到缓存中,有两种机制来加载数据:
- 提前加载Proactive Load——使用这种方式时,你提前将所有的状态数据加载到缓存中,可能在应用程序或线程启动时进行,然后在应用程序或线程的生存期内一直缓存;
- 动态加载Reactive Load——或称反应式加载,当使用这种方法时,在应用程序请求数据时取到数据,并且将它缓存起来以备后续使用。
过期策略[ ]
另外一个关键因素是如何保持缓存数据和主数据(文件或数据库或其他的应用程序资源)的一致性,你可以定义过期策略来决定缓存中的内容,如已经缓存的时间或者收到其他资源的通知。
Asp.net缓存[ ]
将常用的数据保存在内存中对asp的开发人员来说并不陌生,Session对象和Application对象提供键值对来缓存数据,Session对象保存和单个用户有关的数据,Application对象可保留和应用程序有关的数据,每个用户都可以访问。
在Asp.net中,提供了专门用于缓存数据的Cache对象,它的应用范围是应用程序域。生存期是和应用程序紧密相关的,每当应用程序启动的时候就重新创建Cache对象。它域Application对象的主要区别就是提供了专门用于缓存管理的特性,比如依赖和过期策略。
你可以使用Cache对象和它的属性来实现高级的缓存功能,同时可以利用Asp.net Cache来对客户端输出的响应内容进行缓存。关于Asp.net中的缓存技术,有以下内容要介绍:
编程缓存Programmatic Caching[ ]
Cache对象定义在System.Web.Caching命名空间,可以使用HttpContext类的Cache属性或Page对象的Cache属性来得到Cache的引用,Cache对象除了存储键值对以外,还可以存储.net框架的对象。下面介绍相应的依赖和过期策略。
依赖和过期策略[ ]
当向缓存中加数据时,可以指定它的依赖关系来实现在某些情况下强制移除它。可用的方案包括以下几种:
- 1.文件依赖(File Dependency)——当硬盘上的某个(某些)文件更改时,强制移除缓存数据;
如:
- CacheDependency cDependency = new
- CacheDependency(Server.MapPath("authors.XML"));
- Cache.Insert("CachedItem", item, cDependency);
- 2.键值依赖(Key Dependency)——指定缓存中的某个数据项更改时移除。如:
- // Create a cache entry.
- Cache["key1"] = "Value 1";
- // Make key2 dependent on key1.
- String[] dependencyKey = new String[1];
- dependencyKey[0] = "key1";
- CacheDependency dependency = new CacheDependency(null, dependencyKey);
- Cache.Insert("key2", "Value 2", dependency);
- 3.基于时间的过期策略——按照预先定义的时间策略来使数据失效,可以是绝对时间(如某个日期的18:00)也可以是相对现在的相对时间。如:
- /// Absolute expiration
- Cache.Insert("CachedItem", item, null, DateTime.Now.AddSeconds(5),Cache.NoSlidingExpiration);
- /// Sliding expiration
- Cache.Insert("CachedItem", item, null, Cache.NoAbsoluteExpiration,
- TimeSpan.FromSeconds(5));
使用太短和太长的过期时间都不行,不是造成用不上的缓存数据,就是缓存了陈旧的数据并加重了缓存负担,所以可以使用高并发的测试来决定过期时间的最佳值。
对缓存项使用优先级
当运行应用程序的服务器内存不足时,会自动清除缓存中的数据,称为“清除scavenging”。此时,Cache对象根据缓存项的优先级来决定先移除哪些缓存数据,你可以在代码中指定缓存项的优先级。参看MSDN中“CacheItemPriority 枚举”,如:
- Cache.Insert("DSN", connectionString, null, d, t, CacheItemPriority.High, onRemove);
刷新数据(清除缓存)
没有直接的方法来刷新Asp.net的输出缓存,但是有替代方法(设置所有数据失效),比如:Response.Cache.SetExpires(DateTime.Now)
这可以清除缓存,但页面上并不立刻体现出来,直到最初的缓存期结束,比如:<%@ OutputCache Duration="10" VaryByParam="none" %>指令指定的缓存只会在10秒后才清除。通常并不需要清除所有缓存项,你只要重新加载数据更新缓存就够了。
输出缓存(Output Cache)
Page Output Caching将对页面请求的响应放入缓存中,后续对此页面的请求将直接从缓存中得到信息而不是重建此页面。可以通过添加Page指令(高级别,声明实现)来实现,也可以使用HTTPCachePolicy类来实现(低级别,程序实现)。本指南不打算介绍技术细节,只给出如何更好使用的指南和最佳实践。有四方面的内容:
- 决定缓存的内容
- 缓存动态页面
- 控制缓存的位置
- 配置页面输出缓存
页面片断缓存[ ]
- 有时候缓存整个页面并不灵活,同时内存的发但也比较大,这时候应考虑片断缓存。页面片断缓存适合以下类型的数据:
- 创建开销很大的页面片断(控件);
- 包含静态数据的页面片断;
- 可被多个用户使用的页面片断;
- 多个页面共享的页面片断(如公用菜单条)
以下是缓存部分页面的例子:
- // Partial caching for 120 seconds
- [System.Web.UI.PartialCaching(120)]
- public class WebUserControl : System.Web.UI.UserControl
- {
- // Your Web control code
- }