此文章由机器翻译。

Microsoft Azure

使用 Microsoft Azure 中的分布式缓存

Iqbal Khan
Jeremiah Talkar

微软 Azure 正迅速成为云选择.NET 应用程序。 除了其丰富的云功能集,Azure 提供与 Microsoft.NET 框架的完全集成。 它也是一个不错的选择,对于JAVA、 PHP、 红宝石和 Python 应用程序。 许多应用程序移动到 Azure 的是高流量,所以你可以期待的高可扩展性的全力支持。 内存中分布式的缓存,可以是环境的一个可扩展的重要组成部分。

这篇文章将会覆盖一般分布式缓存,它可以提供。

这里描述的功能涉及通用内存中分布式的缓存,并没有特别 Azure 缓存或 NCache azure。为.NET 应用程序部署在 Azure,分布式的内存中缓存具有三个主要的好处:

  1. 应用程序的性能和可扩展性
  2. 缓存ASP.NET会话状态、 视图状态和页输出
  3. 运行时数据共享与事件

应用程序的性能和可扩展性

Azure 很容易地扩展应用程序基础结构。 例如,可以容易地添加更多 Web 角色、 工作者角色或虚拟机 (Vm) 当你预期更高的事务负载。 尽管这种灵活性,数据存储可以是一个可以让你从正在能够扩展您的应用程序的瓶颈。

这是一个内存中的分布式的缓存在哪里可以帮助。 它允许您缓存尽可能多的数据,如你所愿。 它能减少多达 90%的昂贵数据库读取。 这也减少了事务性数据库上的压力。 它将能够更快地执行,并采取在更大的事务负载上。

与关系数据库中,不同的是内存中的分布式的缓存的鳞片以线性方式。 它一般不会成为一个可伸缩性瓶颈,即使 90%的读取流量可能会去而不是数据库缓存。 缓存中的所有数据都分布到多个缓存服务器。 您可以轻松地添加更多的缓存服务器,随着你的事务负载的增加。 图 1 演示如何直接应用到缓存中。

图 1 使用内存中分布式.NET 应用程序中的缓存

// Check the cache before going to the database
  Customer Load(string customerId)
{
// The key for will be like Customer:PK:1000
  string key = "Customers:CustomerID:" + customerId;
  Customer cust = (Customer)Cache[key];
  if (cust == null)
{
// Item not found in the cache; therefore, load from database
  LoadCustomerFromDb(cust);
// Now, add this object to the cache for future reference
  Cache.Insert(key, cust, null,
  Cache.NoAbsoluteExpiration,
  Cache.NoSlidingExpiration,
  CacheItemPriority.Default, null );
}
  return cust;
}

内存中的分布式的缓存可以更快、 更具可扩展性比一个关系数据库。 图 2 显示一些性能数据,以便给你一个想法。 正如你所看到的可伸缩性是线性的。 这与关系数据库或您ASP.NET的会话状态存储比较,你会看到效益。

图 2 为一个典型的分布式缓存的的性能数字

 

簇的大小 每秒读取 每秒写入
2 节点群集 50,000 32,000
3 节点群集 72,000 48,000
4 节点群集 72,000 64,000
5 节点群集 120,000 80,000
6 节点群集 144,000 96,000

ASP.NET会话状态、 视图状态和页输出缓存

使用内存中分布式的缓存中 Azure 还有助于与ASP.NET会话状态、ASP.NET视图状态和ASP.NET输出缓存。 您需要存储在某个地方ASP.NET会话状态。 这可以成为一个主要的可伸缩性瓶颈。 您可以在 Azure,存储在一个 SQL 数据库,Azure 表存储或内存中的分布式的缓存ASP.NET会话状态。

SQL 数据库并不是理想的存储会话状态。 关系数据库从来没有真正为 Blob 存储设计和作为一个 Blob 存储ASP.NET会话状态的对象。 这可以导致的性能问题,成为一个可伸缩性瓶颈。

同样,Azure 表存储不是理想的 Blob 存储。 它被用于存储结构化的实体。 虽然它是比 SQL 数据库可扩展性更强,它是用于存储ASP.NET会话状态仍不理想。

内存中的分布式的缓存是更适合用于存储中 Azure 的ASP.NET会话状态。 它是更快、 更具可扩展性比其他两个选项。 它还将复制会话,所以那里是无数据丢失,如果缓存服务器停机。 如果您在一个单独的专用中存储会话缓存层,然后 Web 角色和 Web 服务器的虚拟机成为无国籍人士,这是好的因为你不会丢失任何会话数据,可以拿。

虽然在高速缓存中运行ASP.NET会话状态是理想从性能的角度看,如果缓存中落下,你的整个应用程序将会降低。 而且,当然,无论是在您的会话也会消失了。 新的穿红衣的缓存为蔚蓝的会话状态提供程序将有一个方法,你可以知道什么时候这些类型的问题发生,至少在清洁的方式将它们显示给用户。

图 3 演示如何配置内存中分布式的缓存来存储ASP.NET会话状态。

图 3 配置ASP.NET会话状态存储在分布式的缓存中

// Check the Cache before going to the database
  Customer Load(string customerId)
{
// The key for will be like Customer:PK:1000
  string key = "Customers:CustomerID:" + customerId;
  Customer cust = (Customer)Cache[key];
  if (cust == null)
{
// Item not found in the cach; therefore, load from database
  LoadCustomerFromDb(cust);
// Now, add this object to the cache for future reference
  Cache.Insert(key, cust, null,
  Cache.NoAbsoluteExpiration,
  Cache.NoSlidingExpiration,
  CacheItemPriority.Default, null );
}
  return cust;
}

虽然ASP.NETMVC 框架已删除需要使用ASP.NET的视图状态,但大多数ASP.NET应用程序还没有尚未移ASP.NETMVC 框架。 因此,他们仍然需要ASP.NET视图状态。

ASP.NET视图状态可以是一个主要的带宽负担,和在你ASP.NET应用程序响应时间造成明显下降。 这是因为ASP.NET视图状态可数百千字节为单位的每个用户。 它是不必要地发送给和在回发的情况下在浏览器中。 如果此ASP.NET视图状态缓存在 Web 服务器端,一个唯一的标识符被发送到浏览器,它可以改善响应时间和也减少带宽消耗。

在 Azure,哪里ASP.NET应用程序运行在多个 Web 角色或虚拟机中,缓存此ASP.NET视图状态的破坏性最小的地方是在内存中的分布式缓存中。 这种方式,你可以在它从任何 Web 服务器。 这里是如何您可以配置ASP.NET视图状态存储在内存中的分布式缓存中:

<!-- /App_Browsers/Default.browser -->
<browsers>
  <browser refID="Default" >
    <controlAdapters>
      <adapter
      controlType="System.Web.UI.Page"
      adapterType="DistCache.Adapters.PageAdapter"/>       
    </controlAdapters>
  </browser>
</browsers>

ASP.NET还提供了一个输出缓存框架,使您可以缓存页输出那是不可能会发生变化。 这种方式,你不需要下一次执行该页面。 这节省了 CPU 资源,加速了ASP.NET的响应时间。 在多服务器部署中,缓存页输出的最佳地点是在一个分布式缓存内所以才会从所有的 Web 服务器访问。 幸运的是,ASP.NET输出缓存有基于提供程序的体系结构,因此,您可以轻松地插入在内存中的分布式缓存中 (请参阅图 4)。

图 4 为内存中分布式缓存配置ASP.NET输出缓存

 

<!-- web.config -->
<system.web>
  <caching>
    <outputCache defaultProvider="DistributedCache">
      <providers>
        <add name="DistributedCache"
          type="Vendor.Web.DistributedCache.DistCacheOutputCacheProvider,
            Vendor.Web.DistributedCache"
          cacheName="default"
          dataCacheClientName="default"/>
      </providers>
    </outputCache>
  </caching>
</system.web>

运行时数据共享通过事件

请考虑使用内存中分布式的缓存中 Azure 的另一个原因是运行时的数据共享。 应用程序通常要运行时数据共享方式如下:

  1. 轮询关系型数据库来检测的数据变化
  2. 使用数据库事件 (如 SqlDependency 或 OracleDepedency)
  3. 使用如 MSMQ 消息队列

所有这些方法提供基本功能,但每个人都有一定的性能和可伸缩性的问题。 轮询通常是一个糟糕的主意。 这涉及到很多不必要的数据库读取。 数据库已经是一个可伸缩性瓶颈,即使没有额外的数据库事件。 与添加的数据库事件的开销,数据库会不会窒息甚至更快地在繁重的事务负载下。

消息队列专攻测序的数据共享和坚持到永久存储区的事件。 他们是不错的情况下在哪里收件人可能无法接收事件很长时间或在哪里应用分布式应用程序在广域网。 然而,当涉及到一个高的交易环境,消息队列可能不执行或鳞片状的内存中分布式缓存。

所以如果您有多个应用程序需要在运行时没有任何测序共享数据和你不需要很长时间坚持事件高交易环境,你可能想要考虑使用内存中的分布式的缓存为运行时的数据共享。 内存中的分布式的缓存允许您在运行时中以各种方式,所有的一切都是异步的共享数据:

  1. 项目级事件的更新,并删除
  2. 高速缓存和组区域级事件
  3. 连续的基于查询的事件
  4. 基于主题的事件 (发布订阅模型)

第三个功能是本质上是不同的方式监视的缓存内的数据更改。 您的应用程序为每个注册的回调。 分布式的缓存是负责"触发事件"每当高速缓存中相应的数据更改。 这个结果在您的应用程序回调被调用。

当更新或移除特定的缓存的项时,将激发项目级事件。 高速缓存和组区域级事件触发时,"容器"中的数据添加、 更新或删除。 连续查询的搜索条件,以在分布式缓存中定义一个数据集由组成。 分布式的缓存将触发事件,每当您添加、 更新或删除此数据集的数据。 您可以使用监视缓存的更改:

string queryString = "SELECT Customers WHERE this.City = ?";
Hashtable values = new Hashtable();
values.Add("City", "New York");
Cache cache = CacheManager.GetCache(cacheName);
ContinuousQuery cQuery = new ContinuousQuery(queryString, values);
cQuery.RegisterAddNotification(
  new CQItemAddedCallback(cqItemAdded));
cQuery.RegisterUpdateNotification(
  new CQItemUpdatedCallback(cqItemUpdated));
cQuery.RegisterRemoveNotification(
  new CQItemRemovedCallback(cqItemRemoved));
cache.RegisterCQ(query);

基于主题的事件是通用的并不绑在缓存中的数据的任何更改。 在这种情况下,缓存客户端负责"触发事件"。分布式的缓存的东西像消息总线变成了和运输这一事件给所有其他客户端连接到缓存中。

与基于主题的事件,您的应用程序可以共享数据在发布/订阅的模型中,一个应用程序在哪里发布的数据并激发基于主题的事件。 其他应用程序等待该事件并开始消费数据,一旦接收到它。

分布式的缓存体系结构

高流量的应用程序不能停机时间。 为在 Azure 中运行这些应用程序,有三个重要方面的分布式的内存中缓存:

  1. 高可用性
  2. 线性的可伸缩性
  3. 数据复制和可靠性

缓存弹性是维持你的内存中分布式的缓存的一个重要方面。 许多内存中分布式的缓存实现弹性和高可用性和以下内容:

自愈合对等缓存群集:所有缓存服务器都形成高速缓存群集。 自我疗愈的对等群集调整自己每当节点中添加或删除。 更强大的缓存形式自愈合等缓存群集,虽然别人构成主从集群。 对等是动态的允许您添加或删除缓存服务器而停止缓存。 主/从集群是有限的因为一个或多个指定节点下阻碍了缓存的操作。 一些缓存如 Memcached 不形成任何缓存群集,因此,不考虑弹性。

连接故障转移中:缓存客户端是在应用程序服务器和 Web 服务器,然后访问缓存服务器上运行的应用程序。 连接故障转移能力是缓存客户端中。 这意味着如果在群集中的任何缓存服务器停机,缓存客户端将继续工作,通过查找在群集中的其他服务器。

动态配置: 两个缓存服务器和缓存客户端具备这种能力。 而不是要求到硬编码配置的详细信息的缓存客户端,缓存服务器传播到缓存客户端在运行时,包括任何更改此信息。

缓存的拓扑

在许多情况下,缓存并不存在于数据库中,如ASP.NET会话状态的数据。 因此,丢失的数据可以是相当痛苦的。 甚至在那里的数据存在于数据库中,失去很多的缓存节点落下时可能严重影响应用程序性能。

因此,它是更好,如果你的内存中分布式的缓存复制您的数据。 不过,复制有性能和存储成本。 一个好的内存中缓存提供了一组缓存拓扑,以处理不同类型的数据存储和复制需要的:

镜像高速缓存:这种拓扑结构有一个积极和一个被动缓存服务器。 所有读取和写入操作都将针对主动节点和更新异步应用于镜像。 这种拓扑结构通常用于当你只能抽出一个专用的高速缓存服务器和共享一个应用程序/Web 服务器作为镜子。

复制缓存:这种拓扑结构有两个或多个活动的缓存服务器。 整个缓存被复制到所有的他们。 所有的更新都是同步的 — — 他们适用于所有缓存服务器作为一个操作。 线性阅读交易规模,当您添加更多的服务器。 缺点是添加更多节点并不增加存储或更新事务的能力。

已分区的缓存:这种拓扑结构有整个缓存分区,与每个缓存服务器包含一个分区。 缓存客户端通常连接到缓存中的所有服务器,这样他们就可以直接访问所需的分区中的数据。 您存储和事务的能力随着您添加更多的服务器,所以那里是线性的可伸缩性。 那里是不能复制,,所以如果高速缓存服务器出现故障,您可能会丢失数据。

分区复制缓存:这就像一个分区的缓存,除了每个分区复制到至少一个其他缓存服务器。 如果缓存服务器停机,你不会失去任何数据。 分区通常活跃,副本是被动的。 您的应用程序永远不会直接与副本进行交互。 这种拓扑结构提供了像线性的可伸缩性,再加上数据的可靠性进行分区缓存的好处。 有轻微的性能和存储成本相关联的复制。

客户端缓存 (近缓存):缓存客户端通常运行在应用程序/Web 服务器上,所以通常访问缓存中涉及到的网络流量。 客户端缓存 (也称为附近高速缓存) 是一个本地的缓存保持经常使用的数据接近您的应用程序并保存网络旅行。 这个本地缓存也是连接和与分布式缓存同步。 客户端缓存可以 InProc (您的应用程序进程内部的意思) 或 OutProc。

部署分布式的缓存中 Azure

在 Azure,你有多个分布式的缓存选项,包括微软 Azure 缓存,Azure 和 Memcached NCache。 每个缓存提供了一组不同的选项。 这些都是单个区域最常用的部署选项:

  1. 在角色缓存 (共同位于或专用)
  2. 缓存服务
  3. 缓存 Vm (专用)
  4. 缓存 Vm 在 WAN (多地区)

在角色缓存您可以部署在角色缓存在 Azure 合用或专用的作用。 共同位于您的应用程序也在该 VM 上运行和专用意味着它运行仅缓存。 一个好的分布式的缓存提供了弹性和高可用性,虽与从添加或删除缓存服务器缓存群集相关的开销。 您的首选项应该是有一个稳定的缓存群集。 你应该添加或删除缓存服务器,只有当你想要扩展或减少您的缓存容量或当你有一个缓存服务器关闭。

在角色缓存是比其他部署选项更不稳定,因为 Azure 可以轻松地启动和停止的角色。 合用的作用,在缓存中也与您的应用程序共享 CPU 和内存资源。 对于一个或两个实例,它是确定以使用此部署选项。 它不是适合于较大的部署,不过,负面的性能影响。

你也可以考虑使用专用的作用在缓存。 铭记的着这种缓存是作为云服务的一部分而部署只是在那服务内可见。 你不能跨多个应用程序共享此缓存。 此外,缓存仅运行,只要您的服务正在运行。 所以,如果你需要有运行甚至当你停止您的应用程序的缓存,不要使用此选项。

微软 Azure 缓存和 azure 两 NCache 提供的角色在部署选项。 你可以 Memcached 运行这种配置的一些调整,但您丢失的数据,如果一个角色被回收,因为 Memcached 不复制数据。

缓存服务在缓存服务分布式的缓存部署独立于您的服务,并为您提供一个高速缓存级别视图。 您分配一定的内存和 CPU 的能力并创建您的缓存。 缓存服务的好处是它的简单性。 你不要安装和配置分布式的缓存软件中的任何你自己。 其结果是,你的缓存管理努力减少因为 Azure 为你管理分布式的缓存群集。 另一个好处是你可以跨多个应用程序共享此缓存。

缓存服务的缺点是您有限的访问权限。 你不能控制或操纵缓存的虚拟机在群集内,你想在一个处所分布式缓存。 此外,您不能部署通读,写通过、 缓存加载程序等等任何服务器端代码。 因为它由 Azure 处理,你不能控制缓存的虚拟机在群集中的数目。 您可以只选择之间基本、 标准和特优的部署选项。 微软 Azure 缓存提供缓存服务部署选项,而 NCache azure 不。

缓存的虚拟机另一个选项是将部署您分布式的缓存中 Azure。 这使您对您的分布式缓存的总体控制。 当您部署 Web 角色、 工作者角色或专用的虚拟机上的应用程序时,您还可以部署分布式缓存 (库) 的客户端部分。 当你创建你的角色时,你也可以安装缓存客户端通过 Windows 安装程序。 这给你更多的安装选择像 OutProc 客户端缓存 (缓存在附近)。

然后你可以作为您的缓存服务器分配单独的专用虚拟机,安装您的分布式的缓存软件和生成基于您的需要您缓存群集。 这些专用的缓存 Vm 稳定,甚至当您的应用程序停止时保持运行。 你缓存客户端会谈到缓存集群通过 TCP 协议。 为高速缓存的虚拟机,有两种部署方案,您可以使用:

  1. 在您的虚拟网络内部署:你的应用程序角色/虚拟机和高速缓存 Vm 都在同一个虚拟网络。 没有您的应用程序和分布式的缓存之间的终结点。 因此,缓存访问是快速的。 高速缓存也是完全隐藏的从外面的世界,因此,更安全。
  2. 在单独的虚拟网络中部署:你的应用程序角色/虚拟机和高速缓存 Vm 都在不同的虚拟网络。 分布式的缓存在它自己的虚拟网络,通过终结点公开。 结果,您可以跨多个应用程序和多个区域共享缓存。 然而,你有你的缓存虚拟机缓存服务比很多更多的控制。

在这两个缓存 VM 部署选项中,你有到缓存中的所有服务器的完全访问权限。 这允许您部署通读、 写通过和缓存加载程序,就像你会在一个处所上部署服务器端代码。 你也有更多的监测信息,因为你到缓存中虚拟机的完全访问权限。 微软 Azure 缓存并不提供缓存 VM 选项,而是在 NCache Azure 和 Memcached 中可用。

微软计划有其托管的缓存中一般可用性 7 月,将取代现有的共享缓存服务。 它最可能不会有一个天蓝色的门户网站存在,将需要 Windows PowerShell 命令行创建和管理。

你可以在专用的虚拟机上安装 NCache azure 和从您的 Web 和工作者角色访问它。 您还可以安装 NCache azure 上 Web 和辅助的角色,但这不是一个推荐的策略。 NCache azure 不来作为缓存服务。 微软 Azure 还提供穿红衣的缓存服务,这是可以通过管理门户。

缓存 Vm 跨湾如果你有一个部署在多个区域中的云服务,考虑通过 WAN 部署你的缓存虚拟机。 在每个区域的缓存 VM 部署是前面的选项相同。 然而,你有两个附加要求的情况为:

  1. 多站点ASP.NET会话:你可以ASP.NET将会话转移从一个网站到另一个如果用户重新路由。 这是经常发生在多个活跃站点中部署的应用程序。 他们可能会重新路由交通处理溢出或者是因为他们把一个站点。
  2. 湾复制的缓存:可以将缓存中的所有更新从一个站点都复制到另一个中。 这可以是一种主动-被动或主动-主动的多站点部署。 在主动-被动,将更新复制在一个方向。 主动-主动,他们是双向。 跨多个站点通过 WAN 复制缓存保持同步,但保持在头脑中它消耗的带宽。

重要的缓存功能

当你使用一个内存中的分布式的缓存时,它将会处理大量的数据。 一个基本的内存中分布式的缓存只提供一个哈希表的关键值) 接口。 企业级分布式的缓存可能会提供以下功能,以及:

搜索功能: 而不是总是找数据基于一个键,它是要搜索基于一些其他逻辑数据的缓存要容易得多。 例如,许多分布式的缓存允许您使用组和标记来进行逻辑分组的缓存的条目。 很多人也让你搜索通过LINQ,缓存是受欢迎的搜索在.NET 框架中的对象。 有些还提供他们自己的对象查询语言 (OQL),一种类似于 SQL 的查询语言,您可以搜索缓存。 搜索一个基于键以外的其他属性的分布式的缓存的能力使得像关系数据库的分布式的缓存外观和感觉。 图 5 显示你可能如何执行这种搜索。

图 5 配置一个分布式缓存LINQ搜索

public IList<Customer> GetCutomers(string city)
{
  // Use LINQ to search distributed cache
  IQueryable<Customer> customers = 
    new DistCacheQuery<Customer>(cache);
  try {
    var result = from customer in customers
      where customer.City = city
      select customer;
    IList<Customer> prods = new List<Customer>();
    foreach (Customer cust in result) {
      customers.Add(cust);
    }
  }
  return customers;
}

通读和写通过/写后面:通读和写通过处理程序简化您的应用程序代码,因为你搬到缓存群集持久性代码一大块。 您的应用程序简单地假定缓存是它的数据存储。 这是另一种方式的跨多个应用程序重用代码。

每当您的应用程序试图取东西不在缓存中 (这被称为"小姐") 中,缓存中调用通读。 当小姐发生缓存中调用通读处理程序,它从您的数据库中提取数据 (请参见图 6)。 分布式的缓存将其放在缓存中,并将其返回到您的应用程序。

图 6 通读处理程序为一个分布式缓存的

public class SqlReadThruProvider : IReadhThruProvider
{
  // Called upon startup to initialize connection
  public void Start(IDictionary parameters) { ... }
  // Called at the end to close connection
  public void Stop() { ... }
  // Responsible for loading object from external data source
  public object Load(string key, ref CacheDependency dep)
  {
    string sql = "SELECT * FROM Customers WHERE ";
    sql += "CustomerID = @ID";
    SqlCommand cmd = new SqlCommand(sql, _connection);
    cmd.Parameters.Add("@ID", System.Data.SqlDbType.VarChar);
      // Extract actual customerID from "key"
      int keyFormatLen = "Customers:CustomerID:".Length;
      string custId = key.Substring(keyFormatLen, 
        key.Length - keyFormatLen);
      cmd.Parameters["@ID"].Value = custId;
    // Fetch the row in the table
    SqlDataReader reader = cmd.ExecuteReader();
    // Copy data from "reader" to "cust" object
    Customers cust = new Customers();
    FillCustomers(reader, cust);
    // Specify a SqlCacheDependency for this object
    dep = new SqlCacheDependency(cmd);
    return cust;
  }
}

高速缓存中也调用写通过处理程序,每当您更新缓存,并且想要它来自动更新数据库。 你写通过处理程序运行在群集和会谈中的一个或多个缓存服务器上对您的数据库。 如果写通过异步调用后的延迟,而不是缓存更新事务的一部分,然而,此操作被称为后写。 后写提高应用程序性能,因为您不必等待完成的数据库更新。

缓存与数据库同步的关系:在一个分布式缓存内的大多数数据来自于您的应用程序数据库。 这意味着现在有两个数据副本,该数据库中的主控副本和一个分布式的缓存中。 如果你有直接更新数据库中的数据的应用程序,但不能访问您在内存中的分布式缓存,到头来把带有陈旧数据在缓存中。

一些分布式的缓存提供数据库同步,以确保缓存中从未有陈旧数据。 这种同步是事件驱动的 (使用数据库通知如 SqlDependency) 或基于轮询的。 事件驱动是更接近于真正的时间,但有更多的开销因为它在数据库服务器中创建单独的相关性每个缓存项。 轮询是效率更高,因为一次数据库调用可以同步数以千计的项目。 但是那里是通常的延迟在同步中,为了避免洪水与不必要的轮询调用数据库。 所以你的选择是之间更接近于实时数据库同步或有轻微的延迟与基于轮询的同步,效率更高。

关系型数据的分布式缓存处理:内存中的分布式的缓存是一个键-值对象存储,但大多数缓存内的数据来自于一个关系数据库。 此数据有一到多、 一对一和多对多的关系。 关系数据库提供的参照完整性约束和级联的更新和删除强制实施这些关系。 高速缓存中也需要类似的东西。

缓冲依赖让您拥有一个缓存的项依赖于另一个。 如果其他缓存的项被更新或删除,则自动删除原始的缓存的项。 这就象是一个级联删除操作。 它是用于处理缓存中的对象之间的一对一和一对多的关系。 一些内存中分布式的缓存执行了此功能,以及。 图 7 显示了您如何将配置缓冲依赖。

图 7 使用缓冲依赖管理高速缓存中的关系

public void CacheCustomerAndOrder(Customer cust, Order order)
{
  Cache cache = HttpRuntime.Cache;
  // Customer has one-to-many with Order. Cache customer first
  // then cache Order and create CacheDependency on customer
  string custKey = "Customer:CustomerId:" + cust.CustomerId;
  cache.Add(custKey, cust, null,
    Cache.NoAbsoluteExpiration,
    Cache.NoSlidingExpiration,
    CacheItemPriority.Default, null);
  // CacheDependency ensures order is removed if Cust updated or removed
  string[] keys = new string[1];
  keys[0] = custKey;
  CacheDependency dep = new CacheDependency(null, keys);
  string orderKey = "Order:CustomerId:" + order.CustomerId
    + ":ProductId:" + order.ProductId;
  // This will cache Order object with CacheDependency on customer
  cache.Add(orderKey, order, dep,
    absolutionExpiration,
    slidingExpiration,
    priority, null);
}

总结

微软 Azure 是一个强大的云计算平台和一个可扩展的环境。 内存中的分布式的缓存可以是这种环境的重要组成部分。 如果您已经在.NET 框架中编写您的应用程序,那么您应该考虑使用.NET 分布式缓存。 如果它是在JAVA中,你有各种JAVA-基于分布式缓存解决方案。 如果你有.NET 和JAVA应用程序的组合,使用一个分布式的缓存,同时支持,并提供数据的可移植性。 大多数的缓存是完全集中于.NET 或JAVA,虽然一些做支持这两个。

对于 PHP、 Ruby、 Python 和其他应用程序,您可以使用 Memcached。 这支持所有这些环境。 Memcached 不是弹性的缓存,因此,具有高可用性和数据-­可靠性的局限性。 无论哪种方式,请记住一个分布式的缓存是您的生产环境的敏感部分。 因此,您必须在您的环境中,彻底评估所有可用的缓存解决方案,选择一个最能满足您的需求。


Iqbal Khan 是为 Alachisoft,为.NET 和微软 Azure 提供 Ncache 分布式缓存技术传教士。你能联系到他在 iqbal@alachisoft.com

Jeremiah Talkar 工程、 咨询和销售是微软开发人员平台传福音企业团队内有 26 年的产品经验的微软 Azure 技术传教士。联系到他在 jtalkar@microsoft.com

感谢以下微软技术专家对本文的审阅:Scott猎人、 政志 Narumoto 和特伦特斯旺森