英文原文:http://msdn.microsoft.com/zh-cn/library/cc511588(en-us).aspx
Enterprise Library 缓存应用程序块允许开发人员在应用程序中合并一个局部缓存,它支持内存内的缓存,和可选的可以是数据库存储或独立存储的后端存储。应用程序块可以不做修改的使用,它提供所有必须的获取、添加和移除缓存数据的功能。可配置的到期和清除策略也是应用程序块的一部分。 在构建企业范围发布的应用程序时,架构和开发人员都要面对许多挑战,缓存可以帮助他们战胜其中的包括下面这些挑战:
普通场景 缓存应用程序块适用于下列性情况:
可以在下列应用程序类型中使用缓存应用程序块:
缓存应用程序块将部署在一个独立的应用程序域中,每个应用程序域可以有一个或多个缓存,有或没有后端存储都可以。缓存不能在不同应用程序域中共享。 缓存应用程序块优化了性能,并且是线程安全和异常安全的。可以扩展它以包含自己的到期策略和后端存储。
示例应用代码 下列代码展示了如何添加一个条目到缓存中,并从缓存中取出一个条目。它创建了一个 Product 类型的对象,然后将它添加到缓存中,一起的还有为2的清除优先级、一条在条目到期后不刷新它的指令、以及从条目最后一次访问开始的5分钟的有效期。
ICacheManager productsCache = CacheFactory.GetCacheManager();
string id = "ProductOneId";
string name = "ProductXYName";
int price = 50;
Product product = new Product(id, name, price);
productsCache.Add(product.ProductID, product, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromMinutes(5)));
// Retrieve the item.
product = (Product) productsCache.GetData(id);
缓存应用程序块的亮点
Enterprise Library 缓存的应用程序块包括以下特性:
决定何时使用缓存的应用程序块
缓存的应用程序块的的设计的目标是当应用程序和缓存存在于同一系统最常见的数据高速缓存的情况。高速缓存是本地这意味着只有该应用程序能够使用。 当它运作是这些指导方针,应用程序块是下列情况理想的解决方案:
此外,缓存应用程序块提供了一个与其他Enterprise Library的应用应用程序块一样的一致的开发模式。 缓存的应用程序块与数据访问的应用程序块为后端存储的功能无缝集成。在相同的方式,安全应用程序块,包括缓存的应用程序块所提供的缓存的能力。开发人员和操作人员使用使用Enterprise Library配置工具配置的应用应用程序块。
替换使用缓存的应用程序块
当有多个应用程序需要使用时,例如,您不能通过Web farm同步缓存时。不过,如果您需要从根本上改变应用程序块的行为您可以通过自定义类来替换CacheManager 类来实现。
使用应用程序块开发应用程序
输入缓存配置信息
这些过程解释了如何配置缓存应用程序块。与节点相关的属性显示在右边的面板中。如果要使用数据访问应用程序块做为后端存储,在配置缓存应用程序块之前就必须配置该应用程序块。 添加应用程序块
配置缓存管理器(Cache Manager)
默认情况下,缓存存储条目仅在内存中,并赋予后端存储的值为 NullBackingStore 。可以配置缓存应用程序块使用数据库缓存存储、独立存储或者定制的存储。数据库缓存存储使用数据访问应用程序块。
为数据库缓存存储配置缓存应用程序块
为独立存储配置缓存应用程序块
为定制缓存存储配置缓存应用程序块
如果要添加另一个缓存、管理器的实例,右单击 CacheManagers 节点,指向 New ,然后单击 CacheManager ,重复前面的步骤。在这只能有一个默认的缓存管理器,每个缓存管理器都必须有唯一的名称。 使用说明 缓存应用程序块的配置设置将影响应用程序的缓存使用模式和它的系统环境,如可用的内存数量。例如,如果应用程序添加了一个比在清除时(这是一个配置设置)移除的缓存的比例大得多的条目到缓存中,缓存将持续增长。随着时间的推移,这将导致内存不足。使用应用程序块的性能计数器来协助为每个应用程序调整配置设置。
添加应用程序代码
缓存应用程序块被设计为支持绝大多数存储数据到缓存中的情况。在添加应用程序代码时,涉及在关键场景中的场景,从中选择一个最适合的情况。使用与场景一起的代码或者按需要修改它。
准备应用程序
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
下一步,添加应用程序代码。通常用二步来创建使用缓存应用程序块的代码:
每个关键场景都示范了如何加入这些步骤到应用程序中。
选择后端存储
每个缓存管理器都可以配置为仅将数据保存在内存中,这意味着它使用的是空后端存储;或者配置为将数据既保存在内存中也保存到持久存储中。持久存储的类型在配置后端存储时指定。后端存储使缓存的数据在应用程序必须重启时得以幸免。在它的初始状态下,缓存应用程序块支持二种持久后端存储,每一种都适用于特定的情况:
开发人员可以扩展缓存应用程序块以支持其他的后端存储类型,有关此主题的更多信息,请参见添加一个新的后端存储。
使用NULL后端存储 空后端存储是配置缓存应用块的默认选择。它不持久化缓存的条目,这意味着缓存的数据仅保存在内存中,而不存在于持久存储中。空后端存储适用于在应用程序重启时要从原始数据源刷新缓存的条目的情况。它可以用于所有支持的应用程序类型,这些类型的列表,请参见缓存应用程序块介绍。 使用独立存储的后端存储 独立存储适用于下列情况:
关于何时使用独立存储的更多信息,请参见 MSDN 上的 Scenarios for Isolated Storage 在配置使用独立存储时,后端存储由缓存实例名称、用户名、程序集和应用程序域来隔离。 独立存储适用于智能客户端和每个应用程序域有自己的缓存的服务器程序。同时也要注意,因为独立存储总是用用户来隔离,所以服务器应用程序必须模拟请求应用程序的用户。 使用数据访问应用程序块后端存储 使用数据访问应用程序块后端存储允许存储缓存的数据到一个数据库中。现在,缓存应用程序块包含一个创建需要的 SQL Server 数据库模式的脚本,并且应用程序块已经测试了对应的 SQL Server 数据库。开发人员可以使用其他类型的数据库做为后端存储,但必须修改应用程序块的源代码。每种数据库类型必须有一个用于数据访问应用程序块的数据库提供程序并包含兼容的模式。 数据访问应用程序块后端存储选项适用于智能客户端和每个应用程序域有自己的缓存的服务器应用程序,以及要访问数据库的情况。 运行在单一应用程序域中的每个 CacheManager 必须使用不同的数据库分区,一个分区定义为应用程序名称和缓存实例名称的组合。数据库可以与使用缓存的应用程序运行在同一服务器上或不同服务器上。数据库支持的使用缓存的应用程序数量仅依赖于数据库的存储限制。
服务器场景的考虑 单一的缓存管理器不能跨应用程序域共享。部署在多台计算机上的服务器应用程序在每台计算机上都有唯一的内存缓存副本,运行在同一计算机上的多个进程也是这样的,包括运行在自己的进程中并使用了缓存应用程序块的企业服务组件。每个进程有自己的内存缓存副本。 不同应用程序不能使用一样的数据访问应用程序块后端存储实例和分区。用缓存应用程序块配置使用同样的数据库实例和分区来运行不同的应用程序将导致不可预知的结果,并且不推荐这样做。 当同样的应用程序运行在多个进程中时(例如,如果应用程序部署在 Web farm 中的多台计算机中),可以使用下列三种方法之一来配置缓存应用程序块:
场景一:分区的缓存
场景一是所有应用程序实例使用同样的数据库实例,但每个应用程序实例使用不同的数据库分区的情形。在这个场景中,每个缓存管理器的操作都是独立的。尽管它们共享了同样的后端存储数据库实例,每个缓存管理器持久缓存数据到不同的分区。此时每个应用程序实例仅有一个有效的缓存。当应用程序重启时,每个缓存管理器从后端存储中的自己的分区中加载它的数据。
如果应用程序预加载缓存,每个部署的应用程序实例都从原始数据源中获取数据。预加载数据使用每个部署的应用程序实例的后端存储储存空间。这意味着在使用缓存的条件下,部署同样的应用程序到多个进程并不比部署不同的应用程序更有效率。
部署同样的应用程序到多台服务器,服务器的每个配置应用程序块都配置为相同的(例如,所有应用程序块使用同样的过期策略),不保证在每个后端存储分区中的数据是相同的。在后端存储分区中的数据复制了配置为使用后端存储分区的缓存管理器的内存缓存数据。内存缓存中的内容随着使用缓存应用程序特定实例而变化,因为应用程序要求路由到不同的服务器,所以每台服务器中内存缓存可能是不同的,因此后端存储分区中的内容也可能是不同的。这意味着,即使所有应用程序同时关闭再重启,也不能保证在每个缓存用后端存储中的数据初始化后其内存缓存中的数据是一样的。
场景二:共享分区
场景二是所有应用程序的实例使用同样的数据库实例和同样的数据库分区,而且所有的缓存管理器都读写缓存。在此场景中,每个应用程序实例操作相互唯一的内存缓存。当应用程序创建一个缓存管理器时,缓存管理器将后端存储中的数据放入内存缓存中,这意味着,如果应用程序在它启动时创建一个缓存管理器,并且如果所有应用程序实例都同时启动的话,每个内存缓存将加载同样的数据。因为应用程序使用了相同的分区,每个应用程序实例不需要在后端存储中的附加存储。
缓存管理器创建的时间是从后端存储加载数据到内存缓存的唯一时间。在此之后,内存缓存中的内容将由使用缓存的应用程序实例所决定。应用程序实例使用缓存的方法可以互不相同,因为需要路由到不同的服务器。运行的不同应用程序实例可以有不同内容的内存缓存。
随着应用程序添加和删除条目,内存缓存的内容会改变,内存缓存的内容在缓存管理器移除或清除过期条目时也会改变。随着内存缓存的改变,缓存管理更新后端存储以反映这些改变。后端存储在它的内存发生改变时不会通知缓存管理器。因此,当一个应用程序实例改变后端存储的内容时,其他应用程序将有与后端存储数据不匹配的内存缓存。这意味着,在应用程序重启以后,内存缓存可以有与在应用程序重启前不一样的内容。
当条目过期时,应用程序可以由缓存管理器提供的提交事件来通知,应用程序可以使用这个通知来从源数据源中刷新缓存的数据。当应用程序添加刷新的缓存条目到缓存中时,缓存管理器也用这些数据更新后端存储。如果应用程序部署在多台计算机上,每个应用程序实例都会收到事件,然后为同样的条目初始化对原始数据源的请求。这多个请求可以对应用程序和原始数据源的性能形成重大的消极影响。因此,使用通知来为刷新过期缓存条目的目的而监视过期在此场景中是不推荐的。
场景三:单一写
场景三是所有应用程序使用同样的数据库实例、同样的数据库分区,而仅有一个缓存管理器可以写缓存,所有的缓存管理器可以从缓存中读。在此场景中,只有一个应用程序实例写缓存,所有其他实用程序实例只能从缓存中读取。可以写缓存的应用程序实例是主机 ,主机的内存缓存与后端存储有着同样的数据。在每个应用程序实例中的内存缓存在缓存管理器创建时用来自后端存储中的数据填充。只能从缓存中读取的应用程序实例获取一个数据快照,因为应用程序实例没有刷新它们的缓存的能力,它们的缓存将在条目过期时失效并缩水。