net环境下的缓存机制.docx

上传人:b****8 文档编号:10957561 上传时间:2023-02-24 格式:DOCX 页数:35 大小:35.69KB
下载 相关 举报
net环境下的缓存机制.docx_第1页
第1页 / 共35页
net环境下的缓存机制.docx_第2页
第2页 / 共35页
net环境下的缓存机制.docx_第3页
第3页 / 共35页
net环境下的缓存机制.docx_第4页
第4页 / 共35页
net环境下的缓存机制.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

net环境下的缓存机制.docx

《net环境下的缓存机制.docx》由会员分享,可在线阅读,更多相关《net环境下的缓存机制.docx(35页珍藏版)》请在冰豆网上搜索。

net环境下的缓存机制.docx

net环境下的缓存机制

.net环境下的缓存机制

.NET环境下的缓存技术

摘要:

介绍缓存的基本概念和常用的缓存技术,给出了各种技术的实现机制和适用范围说明,设计缓存方案应该考虑的问题,以及.NET环境下可用的缓存技术.

1(*)概念

1.1缓存能解决的问题

u性能——将相应数据存储起来以避免数据的重复创建、处理和传输,可有效提高性能。

比如将不改变的数据缓存起来,例如国家列表、市区列表等,能明显提高web程序的反应速度;

u稳定性——同一个应用中,对同一数据、逻辑功能和用户界面的多次请求经常发生。

当用户基数很大时,如果每次请求都进行处理,消耗的资源是很大的浪费,也同时造成系统的不稳定。

例如,web应用中,对一些静态页面的呈现内容进行缓存能有效的节省资源,提高稳定性。

而缓存数据也能降低对数据库的访问次数,降低数据库的负担和提高数据库的服务能力;

u可用性——有时,提供数据信息的服务可能会意外停止,如果使用了缓存技术,可以在一定时间内仍正常提供对最终用户的支持,提高了系统的可用性。

1.2理解状态

缓存可以说是状态管理的框架。

理解状态的含义和它的一些特性——比如生存期和生存范围——对决定是否缓存和选择合适的缓存技术有很大帮助。

状态是指一些数据,在应用系统某个时间点上,数据的状态和条件。

这些数据可能是永久性的存储在数据库中,可能是只在内存里停留一会,也可能是按照某个逻辑存活(比如多长时间后释放),它的应用范围可能是所有用户可访问,可能是单个用户有权限;

1.2.1状态的生存期

生存期是指数据保持有效性的时间区间,也就是从创建到移除的时间间隔。

通常的生存期有以下几种:

Ø永久状态PermanentState——应用程序使用的永久数据;

Ø进程状态ProcessState——只在进程周期内有效;(进程的三种状态:

运行、阻塞、就绪)

Ø会话状态SessionState——和特定的用户会话有关;

Ø消息状态MessageState——处理某个消息的时间内有效;

1.2.2状态的范围

状态的范围指对该状态有访问权限的物理或逻辑范围。

Ø物理范围指可以被访问到的状态数据存放的物理位置,通常包括:

1、组织Organization——在一个组织内的所有应用程序可以访问状态数据;

2、场Farm——在应用场范围内的任何机器上都可以访问;(WEB场:

许多服务器共同承担响应用户申请的责任,用户的请求并不总是被路由到同一个服务器,而是被称为”负载平衡”进程的特殊软件对URL站点的申请分配任意一个空闲的服务器.)

3、机器Machine——单个机器范围内可以访问;

4、进程Process——进程内的访问许可;

5、应用域AppDomain——应用程序域内的访问许可。

Ø逻辑范围指可访问状态数据的逻辑范围,常见的有:

1、应用程序Application;

2、业务流程BusinessProcess;

3、角色Role;(按照一致的权限招待相应操作的个体)

4、用户User;

1.2.3状态数据的陈旧

缓存的状态数据只是主数据(MasterStateData)的快照,由于数据源可能被修改,所以状态数据就有陈旧的特性。

合理利用此特性和将数据陈旧的负面影响最小化是缓存状态数据的一个重要任务。

可以依据以下方式定义数据的陈旧依据:

主数据更改的可能性——随着时间的推进,主数据更改的可能是否大大增加?

按照这一点来决定缓存状态数据的陈旧;

更改的相关性——主数据更新时,缓存的状态数据不相应更新是不是造成影响系统的使用?

比如,更改系统的外观风格并不会对业务造成很大影响。

1.2.4状态数据陈旧的容忍度

缓存状态数据的陈旧对业务流程的影响称为容忍度,应用系统的可以为不能容忍(NoTolerance)和一定程度的容忍(someTolerance),前者必须和主数据同步更新,后者允许一定时间或一定范围的陈旧,判断标准就是对业务流程的影响度。

1.2.5理解状态数据的转换过程

状态的另一个属性是在不同阶段的表现形式。

在数据库中存储的是原始格式的数据,业务流程中的是处理过的数据,给最终用户呈现的则是另外的形式。

如下表所示:

决定缓存数据时,应该考虑缓存哪个阶段(哪种形式)的状态数据。

以下方针有助于做决定:

Ø当业务逻辑可以容忍缓存数据的陈旧时就缓存原始数据;原始数据可以缓存在数据库访问组件和服务代理中;

Ø缓存处理过的数据以减少处理时间和资源;处理过的数据可以缓存在业务逻辑组件和服务接口中。

Ø当需要呈现的数据量很大并且控件的呈现时间很长时,缓存呈现数据(比如包含大数据量的Treeview控件)。

这种数据应该被缓存在UI控件中。

1.3(*)为什么要缓存数据

在应用程序中缓存数据有以下好处:

减少交互的通讯量——缓存数据能有效减少在进程和机器间的传输量;

降低系统中的处理量——减少处理次数;

降低需要做的磁盘访问次数——比如缓存在内存中的数据。

1.4数据应该被缓存在哪里

缓存数据只是一份主数据的拷贝,它可能在内存中或以不同的表现形式保存在硬盘上,也就是说,离数据的使用者越近越好。

所以,除了考虑要缓存哪些数据以外,数据缓存在哪里也是一个主要的考量点。

分为以下两个范围:

1、存储类型StorageType—数据可用的物理存储位置;

2、层间的架构元素(Layeredarchitectureelements)—数据可用的逻辑存储位置。

1.4.1存储类型

缓存有很多实现方法,可以被分为两类,基于内存的缓存和基于磁盘的缓存:

1、内存驻留缓存——包含在内存中临时存储数据的所有实现方法,通常使用情况:

a)应用程序频繁使用同样的数据;

b)应用程序需要经常获取数据;

通过将数据保留在内存中,可以有效降低昂贵的磁盘访问操作,也可以通过将数据保留在使用者进程中来最大程度的减少跨进程的数据传输。

2、磁盘驻留缓存——包含所有使用磁盘作为存储介质的缓存技术,如文件和数据库。

以下情况基于磁盘的缓存是很有效的:

a)处理大数据量时;

b)应用服务提供的数据可能并不是总能使用(比如离线的情况);

c)缓存的数据必须能在进程回收和机器重启的情况下保持有效;

通过缓存处理过的数据,可以有效降低数据处理的负担,同时可减少数据交互的代价。

1.4.2架构间元素

应用程序中的每个逻辑层的组件都会处理数据,下图标识了一些通用组件:

当使用这些组件进行工作时,需要考虑哪些数据可以被缓存起来,还有以哪种方式进行缓存会对程序的整体性能和可用性有帮助,以上的这些元素都可以缓存相应的数据。

1.5实施缓存时的考虑

当设计缓存方案时,不但要考虑缓存哪些数据、数据缓存到哪里,还有因素需要考虑。

1.5.1格式和访问模式

当决定是否缓存一个对象时,关于数据的格式和访问机制,需要考虑三个主要问题:

1、线程安全——当缓存的内容可以被多个线程访问时,使用某种锁定机制来保证数据不会被两个线程同时操作;

2、序列化——将一个对象缓存时,需要将它序列化以便保存,所以包缓存的对象必须支持序列化;

3、规格化缓存数据——缓存数据时,相对于要使用的数据格式而言,要保证数据的格式是优化过的。

1.5.2内容加载

在使用缓存数据前,必须将数据加载到缓存中,有两种机制来加载数据:

·提前加载ProactiveLoad——使用这种方式时,提前将所有的状态数据加载到缓存中,可能在应用程序或线程启动时进行,然后在应用程序或线程的生存期内一直缓存;

·动态加载ReactiveLoad——或称反应式加载,当使用这种方法时,在应用程序请求数据时取到数据,并且将它缓存起来以备后续使用。

1.5.3(*)过期策略

另外一个关键因素是定义过期策略保持缓存数据和主数据(文件或数据库或其他的应用程序资源)的一致性,如已经缓存的时间或者收到其他资源的通知。

1.5.4(*)安全性

当缓存数据时,需要非常清楚缓存中数据的潜在安全威胁。

缓存中的数据可能会被别的进程访问或修改,而此进程对主数据是没有权限的。

原因是当数据存储在原始位置时,有相应的安全机制来保护它,当数据被带出传统的安全边界时,需要有同等的安全机制。

1.5.5(*)管理

缓存数据时,应用系统需要的维护工作加大了。

在发布应用程序时,需要對緩存配置相应的属性,比如缓存的大小限制和清除策略。

同时要使用某种机制来监控缓存的效率(比如事件日志和性能计数器)

2缓存技术

下面主要介绍以下技术:

Ø使用Asp.Net缓存;

Ø使用内存映射文件;

Ø使用SQLServer缓存;

Ø使用静态变量缓存;

Ø使用A会话状态(SessionState);

Ø使用A客户端缓存和状态;

2.1A缓存

ASP.NET提供了两种基本的缓存机制来提供缓存功能。

一种是应用程序缓存,它允许开发者将程序生成的数据或报表业务对象放入缓存中。

另一种是页输出缓存,可以直接获取存放在缓存中的页面,而不需要经过繁杂的对该页面的再次处理。

在.NetFramework中,应用程序缓存通过System.Web.Caching.Cache类实现。

它是一个密封类,不能被继承。

对于每一个应用程序域,都要创建一个Cache类的实例,其生命周期与应用程序域的生命周期保持一致。

每当应用程序启动的时候就重新创建Cache对象。

它和Application对象的主要区别就是提供了专门用于缓存管理的特性,比如依赖和过期策略。

可以使用Cache对象和它的属性来实现高级的缓存功能,同时可以利用ACache来对客户端输出的响应内容进行缓存。

应用程序缓存是通过ASP.NET管理内存中的缓存空间。

放入缓存中的应用程序数据对象,以键值对的方式存储,这便于用户在访问缓存中的数据项时,可以根据key值判断该项是否存在缓存中。

2.1.1编程缓存ProgrammaticCaching

Cache对象定义在System.Web.Caching命名空间,可以使用HttpContext类的Cache属性或Page的Cache属性来得到Cache的引用,Cache对象除了存储键值对以外,还可以存储.net框架的对象。

2.1.1.1依赖和过期策略

向缓存中加数据时,指定它的依赖关系来实现在某些情况下强制移除它。

方案包括以下几种:

文件依赖(FileDependency)——当硬盘上的某个(某些)文件更改时,强制移除缓存数据;如:

CacheDependencycDependency=newCacheDependency(Server.MapPath("authors.xml"));

Cache.Insert("CachedItem",item,cDependency);

键值依赖(KeyDependency)——指定缓存中的某个数据项更改时移除。

如:

//创建一个缓存条目

Cache["key1"]="Value1";

//创建key2依赖于key1

String[]dependencyKey=newString[1];

dependencyKey[0]=“key1”;

//创建CacheDependency类关联缓存依赖项的实例

CacheDependencydependency=newCacheDependency(null,dependencyKey);

Cache.Insert("key2","Value2",dependency);

·基于时间的过期策略——来使数据失效,可以是绝对时间也可以是相对现在的相对时间。

如:

/*绝对过期(NoAbsoluteExpiration可以设置缓存的绝对过期时间*/

Cache.Insert("CachedItem",item,null,Cache.NoSlidingExpiration,DateTime.Now.AddSeconds(30));

/*相对过期(NoSlidingExpiration设置相对过期时间,如果缓存在设定的时间内没有被访问,缓存过期;如果有访问,则缓存过期时间将会重置为原始值*/

Cache.Insert("CachedItem",item,null,Cache.NoAbsoluteExpiration,TimeSpan.FromSeconds(20));

使用太短和太长的过期时间都不行,不是造成用不上的缓存数据,就是缓存了陈旧的数据并加重了缓存负担,所以可以使用高并发的测试来决定过期时间的最佳值。

 

2.1.2实现对数据库的依赖

这就要求实现通知机制,当数据库数据改变时能够通知你的缓存数据改变

SqlCacheDependency说简单些就是当数据库的数据发生改变的时候使依赖于此数据库(表)的缓存自动过期。

SqlCacheDependency又分为SqlServer2000的基于轮询(Polling)的拉机制,和SqlServer2005基于通知(Notification)的推机制两种不同策略。

而应用System.Web.Caching.Cache时不能应用SqlCacheDependency过期策略,只能应用基于某个文件改变或其他Cache项目改变的过期策略。

(轮询(Polling)机制意思是说Asp.Net进程每隔一段时间就对数据库进程进行一次访问,因为间隔时间是固定的,所以叫轮询(访问时间以毫秒为单位,可以在Web.Config里设置)。

当某次轮询时发现与上一次访问时的数据不一样,那么就立刻使依赖于此数据的缓存过期。

通知(Notification)机制是说Asp.Net只管做自己的事情,不对数据库进程进行询问,而当数据库的数据发生变动时,进程主动通知Asp.Net进程,数据发生了改变,然后Asp.Net让缓存过期。

由此可见,使用SqlServer2005的通知机制效率要高得多。

数据库上的ASP.NET缓存依赖

利用SQLServer的系统存储过程sp_makewebtask,是可以达到这个目的,在触发器中使用它,可以取得一个合理有效的途径使在CacheDependency实例中的文件监视进程侦测到文件的变化,从而使缓存失效。

事实上,因为CacheDependency类工作在UNC文件协议上,可以在整个WebFarm上部署这个解决方案,WebFarm上每台机器的应用程序副本都会通过UNC文件路径来监视WebFarm中某台单个机器上的同一个文件.

(通用命名规则(UNC):

一种对文件的命名规则,它提供了独立于机器的文件定位方式。

UNC名称使用\\server\share\path\filename这一语法格式,而不是指定驱动器符和路径。

2.1.2.1使用SQLServer中信赖的Northwind范例数据库。

创建一个简单的DataGrid来显示Employees表中的记录.

1.创建触发器

  CREATETRIGGERWriteCacheDepFileON[dbo].[Employees]

  FORINSERT,UPDATE,DELETE

  AS

  EXECsp_makewebtask'\\peter\C$\Cache\mycache.txt','SELECTtop1FirstNameFROMemployees'

 存储过程就是告诉SQLServer,如果Employee表发生任何变动,就根据一个简单的查询来更新”mycache.txt”文件,只要它是一个有效的T-SQL语句,SQLServer就会去更新那个文件。

2.创建一个目录,并设为共享。

可能要更新该文件的访问权限,以使它可以被写入。

注意,使用的是管理员共享”C$”.

3.创建一个空的文本文件

在创建的共享目录下,创建文本文件"mycache.txt".

4.创建用程序

首先,在web.config文件中输入依赖文件名称,这样做可以使在修改依赖文件的时候不需要重新部署应用程序。

  在web.config文件的根部,添加appSettings配置节:

 <appSettings>

  //缓存依赖文件路径

  <addkey="dependencyFile"value="\\peter\Cache\mycache.txt"/>

  </appSettings>

  </configuration>

5.在Global类中建立缓存机制

这样就不需要在任何页面中编写特定的代码.

 

在Global类中建立缓存机制

  publicclassGlobal:

System.Web.HttpApplication

  {

  Cache_cache=null;

  publicstaticboolblnReflash=false;

  publicconststringConnStr="server=localhost;database=Northwind;uid=sa;pwd=";

  publicconststringstrSQL="SELECTEmployeeID,lastname,firstnameFROMEmployees";

  protectedvoidApplication_Start(Objectsender,EventArgse)

  {

  _cache=Context.Cache;//定义一个Cache类型的_cache对象,把Cache实例赋给它

  RefreshCahe(null,null,0);//调用RefreshCache方法填充该对象

  }

  protectedvoidSession_Start(Objectsender,EventArgse)

  {if(HttpContext.Current.Cache["Employees"]==null)

  RefreshCache(null,null,0);//调用RefreshCache方法填充缓存,確保可用

  }//RefreshCache静态的委托回调方法,被监控的文件变化时,即缓存失效时,调用该委托刷新缓存中的数据

  staticvoidRefreshCache(stringkey,objectitem,CacheItemRemoveReasonreason)

  {

  SqlDataAdapteradapter=newSqlDataAdapter(strSQL,ConnStr);

  DataSetds=newDataSet();

  adapter.Fill(ds,"Employees");

  CacheItemRemovedCallbackonRemove=newCacheItemRemovedCallback(RefreshCache);

  stringdepFile=ConfigurationSettings.AppSettings["dependencyFile"].ToString();

  HttpContext.Current.Cache.Insert("Employees",ds,newCacheDependency(depFile),

  Cache.NoAbsoluteExpiration,Cache.NoSlidingExpiration,

  CacheItemPriority.High,onRemove);

  blnReflash=true;

  }

  }

  

RefreshCache实际上是一个静态的委托回调方法,就是简单的从Empoyees表中取得一个DataSet,然后。

创建CacheItemRemovedCallback类型的委托OnRemove,使其指向RefreshCache方法,当被监控的文件变化时,也就是缓存失效时,就会调用该委托,刷新缓存中的数据。

 最后把DataSet连同OnRemove委托一起插入到缓存中,在Session_Start中,为了“保险“,另外添加了一个判断来调用RefreshCache方法填充缓存。

应用程序就创建好了,在任何页面中都可以访问到缓存的DataSet。

在WebForm1的aspx.cs中,如何使用它呢?

  privatevoidPage_Load(objectsender,System.EventArgse)

  {

  //保证缓存非空,如果为空,则填充它

  if(Cache["Employees"]==null)

{

Global.RefreshCache(null,null,0);

  cacheStatus.Text="CacheRefreshedat"+DateTime.Now.ToLongTimeString();

}

  else

  cacheStatus.Text="DataSetfromCache";

  

  DataSetds=(DataSet)Cache["Employees"];

  DataGrid1.DataSource=ds.Tables[0];

  DataGrid1.DataBind();

  }

  现在,如果请求这个页面,它将会每次成功的显示从从Cache中取得的DataSet。

或者是:

不在Global类中建立,在web.config里面添加一些内容就可以使用了。

1、首先添加数据库连接串:

<connectionStrings>

<addname="pubsConString"connectionString="server=localhost;database=pubs;uid=sa;pwd=mypassword;"/>

</connectionStrings>

2、其次添加caching节:

<system.web>

<caching>

<sqlCacheDependencyenabled="true">

<databases>

<addname="pubs"connectionStringName="pubsConString"pollTime="900"/>

</databases>

</sqlCacheDependency>

</caching>

</system.web>

下面是测试代码,当页面加载的时候执行如下代码:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 经济学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1