现在的位置: 首页 > 综合 > 正文

.Net环境下的缓存技术介绍

2011年02月03日 ⁄ 综合 ⁄ 共 5936字 ⁄ 字号 评论关闭

 

摘要: 介绍缓存的基本概念和常用的缓存技术,给出了各种技术的实现机制的简单介绍和适用范围说明,以及设计缓存方案应该考虑的问题(共17页)

1         概念

1.1   缓存能解决的问题

· 性能——将相应数据存储起来以避免数据的重复创建、处理和传输,可有效提高性能。比如将不改变的数据缓存起来,例如国家列表等,这样能明显提高web程序的反应速度;

· 稳定性——同一个应用中,对同一数据、逻辑功能和用户界面的多次请求时经常发生的。当用户基数很大时,如果每次请求都进行处理,消耗的资源是很大的浪费,也同时造成系统的不稳定。例如,web应用中,对一些静态页面的呈现内容进行缓存能有效的节省资源,提高稳定性。而缓存数据也能降低对数据库的访问次数,降低数据库的负担和提高数据库的服务能力;

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

1.2   理解状态

在深入介绍缓存技术之前,需要对状态有一个认识,因为缓存可以说是状态管理的框架。理解状态的含义和它的一些特性——比如生存期和生存范围——对决定是否缓存和选择合适的缓存技术有很大帮助。状态是指一些数据,在应用系统某个时间点上,数据的状态和条件。这些数据可能是永久性的存储在数据库中,可能是只在内存里停留一会,也可能是按照某个逻辑存活(比如多长时间后释放),它的应用范围可能是所有用户可访问,可能是单个用户有权限;

1.2.1  状态的生存期

生存期是指数据保持有效性的时间区间,也就是从创建到移除的时间间隔。通常的生存期有以下几种:

·永久状态Permanent State——应用程序使用的永久数据;

·进程状态Process State——只在进程周期内有效;

·会话状态Session State——和特定的用户会话有关;

·消息状态Message State——处理某个消息的时间内有效;

1.2.2  状态的范围

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

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

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

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

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

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

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

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

1、  应用程序Application

2、  业务流程Business Process

3、  角色Role

4、  用户User

1.2.3  状态数据的陈旧

缓存的状态数据只是主数据(Master State Data)的快照,由于数据源可能被修改,所以状态数据就有会陈旧的特性。合理利用此特性和将数据陈旧的负面影响最小化是缓存状态数据的一个重要任务。你可以以一下方式定义数据的陈旧依据:

·主数据更改的可能性——随着时间的推进,主数据更改的可能是否大大增加?安照这一点来决定缓存状态数据的陈旧;

·更改的相关性——主数据更新时,缓存的状态数据不相应更新是不是造成影响系统的使用?比如,更改系统的外观风格并不会对业务造成很大影响。

1.2.4  状态数据陈旧的容忍度

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

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

状态的另一个属性是在不同阶段的表现形式。在数据库中存储的是原始格式的数据,业务流程中的是处理过的数据,给最终用户呈现的则是另外的形式。如下表所示:

表现形式

描述

举例

原始数据

数据的原始形式

如数据库中的数据

处理过的数据

业务流程中对原始数据加工后的数据

业务过程中的数据形式

呈现形式

可呈现给最终用户的形式

HTML或可理解的文字说明

当决定缓存数据时,应该考虑缓存哪个阶段(哪种形式)的状态数据。以下方针有助于你做决定:

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

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

·当需要呈现的数据量很大并且控件的呈现时间很长时,缓存呈现数据(比如包含大数据量的Treeview控件)。这种数据应该被缓存在UI控件中。

1.3   为什么要缓存数据

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

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

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

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

1.4   数据应该被缓存在哪里

缓存数据只是一份主数据的拷贝,它可能在内存中或以不同的表现形式保存在硬盘上,也就是说,离说句的使用者越近越好。所以,除了考虑要缓存哪些数据以外,数据缓存在哪里也是一个主要的考量点。这个问题分为以下两个范围:

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

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

1.4.1  存储类型

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

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

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

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

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

2、  磁盘驻留缓存——这种技术包含所有使用磁盘作为存储介质的缓存技术,如文件和数据库。在以下情况下基于磁盘的缓存是很有效的:

a)       处理大数据量时;

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

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

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

1.4.2  架构间元素

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


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

1.5   实施缓存时的考虑

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

1.5.1  格式和访问模式

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

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

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

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

1.5.2  内容加载

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

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

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

1.5.3  过期策略

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

1.5.4  安全性

当缓存数据时,需要非常清楚缓存中数据的潜在安全威胁。缓存中的数据可能会被别的进程访问或修改,而此进程对主数据是没有权限的。原因是当数据存储在原始位置时,有相应的安全机制来保护它,当数据被带出传统的安全边界时,需要有同等的安全机制。

1.5.5  管理

当你缓存数据时,应用系统需要的维护工作加大了。在发布应用程序时,需要配置相应的属性,比如缓存的大小限制和清除策略。同时要使用某种机制来监控缓存的效率(比如事件日志和性能计数器)

1.6   小结

第一节内容简单介绍了缓存技术中的概念、缓存数据的原因和方案、优势、实施缓存方案时的考虑等基本内容。现在你对缓存中涉及的内容有了一个大致了解,下面着重介绍可用的缓存技术。

2         缓存技术

本节将介绍以下技术:

使用Asp.Net缓存;

使用Remoting Singleton缓存;

使用内存映射文件;

使用SQL Server缓存;

使用静态变量缓存;

使用Asp.net 会话状态(Session State)

使用Asp.net客户端缓存和状态;

使用Internet Explorer缓存。

2.1             Asp.net缓存

将常用的数据保存在内存中对asp的开发人员来说并不陌生,Session对象和Application对象提供键值对来缓存数据,Session对象保存和单个用户有关的数据,Application对象可保留和应用程序有关的数据,每个用户都可以访问。

Asp.net中,提供了专门用于缓存数据的Cache对象,它的应用范围是应用程序域。生存期是和应用程序紧密相关的,每当应用程序启动的时候就重新创建Cache对象。它域Application对象的主要区别就是提供了专门用于缓存管理的特性,比如依赖和过期策略。

你可以使用Cache对象和它的属性来实现高级的缓存功能,同时可以利用Asp.net Cache来对客户端输出的响应内容进行缓存。关于Asp.net中的缓存技术,有以下内容要介绍:

2.1.1  编程缓存Programmatic Caching

Cache对象定义在System.Web.Caching命名空间,可以使用HttpContext类的Cache属性或Page对象的Cache属性来得到Cache的引用,Cache对象除了存储键值对以外,还可以存储.net框架的对象。下面介绍相应的依赖和过期策略。

2.1.1.1 依赖和过期策略

当向缓存中加数据时,可以指定它的依赖关系来实现在某些情况下强制移除它。可用的方案包括以下几种:

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

CacheDependency cDependency = new

CacheDependency(Server.MapPath("authors.xml"));

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

·键值依赖(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);

·基于时间的过期策略——按照预先定义的时间策略来使数据失效,可以是绝对时间(如某个日期的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));

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

·另外有个问题就是如何实现对数据库的依赖,这就要求实现自己的通知机制,当数据库数据改变时能够通知你的缓存数据改变。可参考http://www.gotdotnet.com/team/rhoward的示例。

由于数据会过期,所以当使用缓存中的数据时,必须检查数据的有效性。如以下代码:

string data = (string)Cache["MyItem"];

if (data == null)

{

data = GetData();

Cache.Insert("MyItem", data);

}

DoSomeThingWithData(data);

依赖和过期策略指定了缓存中数据的移除方式,有时候你可能需要在移除发生时做一些工作,这能靠写代码来实现这一点,这就是我们要讲到的。

2.1.1.2 使用缓存回调(Cache Callback

你可以定义回调,这样当移除自动发生时, 你可以不移除它或者使用新的数据来替换它。如:

CacheItemRemovedCallback onRemove = new CacheItemRemovedCallback(this.RemovedCallback);

Cache.Insert("CachedItem",

item,

null,

Cache.NoAbsoluteExpiration,

Cache.NoSlidingExpiration,

CacheItemPriority.Default,

onRemove);

// Implement the function to handle the expiration of the cache.

public void RemovedCallback(string key, object value, CacheItemRemovedReason r)

{

// Test whether the item is expired, and reinsert it into the cache.

if (r == CacheItemRemovedReason.Expired)

{

// Reinsert it into the cache again.

CacheItemRemov

抱歉!评论已关闭.