使用分布式缓存的可扩展 WCF 应用程序

作者:伊克巴尔汗

在为适应高流量使用而出现的 Web 应用程序爆炸式增长之后,下一波浪潮已成为面向服务的架构 (SOA)。 SOA 改变了应用程序开发和集成环境。 它注定会成为开发极具扩展性的应用程序的标准方式,而 Windows Azure 和 Windows Communication Foundation (WCF) 等云计算平台代表着 SOA 朝着实现这一目标迈进的巨大飞跃。 SOA 的主要目的是实现可伸缩性并维持尽可能多的负载,以提高敏捷性和生产力。

不过,就应用程序架构而言,真正的 SOA 应用程序应该可以轻松扩展。 但是,要实现真正的可扩展性,需要解决许多性能瓶颈。

  • 到目前为止,应用程序数据是 WCF 服务中使用量最大的数据,其存储和访问是主要的可伸缩性瓶颈,因为延迟是关系数据访问的副产品。
  • 具有高度分布和不同数据源的环境对实现 SOA 的性能目标构成最大挑战。 尽管应用层可以很好地扩展,但面向服务的架构 (SOA) 中仍然存在的主要问题之一是参与数据服务的性能。
  • 就事务处理能力而言,数据层无法以线性方式扩展,因此可能会导致整体响应时间出现相当大的延迟。
  • 此外,SOA 服务依赖于其他服务,这些服务可能在本地不可用,因此对其他服务的 WAN 调用可能成为另一个瓶颈。
  • 此外,如果在数据虚拟化层的实现中使用 SOA,则数据服务的性能至关重要,在这种情况下,应用程序的性能与获取底层数据所需的时间成正比。 数据服务可能同时访问关系和非关系数据,这些数据通常分布在多个地理分布的数据中心,这可能会导致响应延迟,从而影响整体应用程序性能。

分布式缓存(NCache) 用于服务可扩展性

为了减少整个解决方案的响应延迟,一个包罗万象的方法是利用高性能缓存系统与数据服务或数据虚拟化层一起使用。 SOA 服务处理两种类型的数据。 一种是服务状态数据,另一种是驻留在数据库中的服务结果数据。 两者都会导致可扩展性瓶颈。

缓存可以在提高访问服务状态和应用程序数据的速度方面发挥非常重要的作用,同时能够同时扩展服务。 缓存通过最小化使用缓存的服务和底层数据提供者之间的流量和延迟来实现这一点。 图 1 描述了使用 NCache 分布式缓存来实现这一点。

创新中心 NCache 分布式缓存可以减轻数据源的压力
图 1:如何 NCache 分布式缓存可以减轻数据源的压力

缓存应用程序数据

分布式缓存,如 NCache 用于根据 WCF 服务在几个小时的小窗口内需要的内容,仅缓存数据库中的数据子集。 分布式缓存可以显着提升 SOA 应用程序的可扩展性,因为:

  • 分布式缓存可以根据其采用的架构进行横向扩展。
  • 它使事情分布在多台服务器上——并且仍然为您的 SOA 应用程序提供一个逻辑视图,因此您认为它只是一个缓存。 但是缓存实际上存在于多个服务器上,这就是缓存真正扩展的原因。
  • 如果您使用分布式缓存,例如 NCache 在服务层和数据库之间,您将显着提高服务层的性能和可伸缩性,因为它将节省大量耗时的数据库访问。

实现的基本逻辑是,在去数据库之前,检查缓存是否已经有数据。 如果是,请从缓存中取出。 否则,就去数据库取数据,放到缓存中,以备下次使用。 图 2 显示了一个示例。

using System.ServiceModel;
using Alachisoft.NCache.Web.Caching;

namespace MyWcfServiceLibrary {
  [ServiceBehavior]
  public class EmployeeService : IEmployeeService {
    static string _sCacheName = "myServiceCache";
    static Cache _sCache = 
      NCache.InitializeCache(_sCacheName);

    public Employee Load(string employeeId) {
// Create a key to lookup in the cache.
      // The key for will be like "Employees:PK:1000".
      string key = "Employee:EmployeeId:" + employeeId;

      Employee employee = (Employee)_sCache[key];
      if (employee == null) {// item not found in the cache. 
        // Therefore, load from database.
        LoadEmployeeFromDb(employee);

        // Now, add to cache for future reference.
       _sCache.Insert(key, employee, null,
          Cache.NoAbsoluteExpiration,
          Cache.NoSlidingExpiration,
          CacheItemPriority.Default);
      }

      // Return a copy of the object since ASP.NET Cache is InProc.
      return employee;
    }
  }
}
图 2 - WCF 服务使用 NCache - 分布式缓存

重要的缓存功能

服务的缓存设计必须考虑以下问题:底层数据更改的频率、缓存数据需要更新的频率、数据是用户特定的还是应用程序范围的、使用什么机制来指示缓存需要更新,应用程序对脏数据的容忍度等。因此,缓存解决方案必须具有对所有此类需求进行排序的必要功能。

下面简要介绍使用分布式缓存通过数据服务对数据进行可扩展管理的一些关键特性。

即将过期的缓存数据

Expirations 允许您指定数据在缓存自动删除之前应在缓存中保留多长时间。 您可以在中指定两种类型的到期时间 NCache:绝对时间到期和滑动或空闲时间到期。

如果缓存中的数据也存在于数据库中,那么您就知道其他用户或可能无法访问您的缓存的应用程序可以在数据库中更改此数据。 发生这种情况时,缓存中的数据会变得陈旧,这是您不希望的。 如果您能够猜测您认为将此数据保存在缓存中的安全时间,您可以指定绝对时间到期。 此外,对于在分布式缓存中存储会话的基于会话的应用程序,滑动过期非常方便。

将缓存与数据库同步

之所以需要数据库同步,是因为数据库实际上是在多个应用程序之间共享的,并且并非所有这些应用程序都可以访问您的缓存。 如果您的 WCF 服务应用程序是唯一更新数据库的应用程序,并且它也可以轻松更新缓存,那么您可能不需要数据库同步功能。

但是,在现实生活环境中,情况并非总是如此。 第三方应用程序更新数据库中的数据,您的缓存与数据库不一致。 将缓存与数据库同步可确保缓存始终了解这些数据库更改并可以相应地进行自我更新。

与数据库同步通常意味着使缓存中的相关缓存项无效,因此下次您的应用程序需要它时,它必须从数据库中获取它,因为缓存没有它。

管理缓存中的数据关系

大多数数据来自关系数据库,即使不是来自关系数据库,它本质上也是关系的。 例如,您试图缓存一个客户对象和一个订单对象,并且这两个对象都是相关的。 一个客户可以有多个订单。

当您拥有这些关系时,您需要能够在缓存中处理它们。 这意味着缓存应该知道客户和订单之间的关系。 如果您从缓存中更新或删除客户,您可能希望缓存自动从缓存中删除订单对象。 这有助于在许多情况下保持数据完整性。

如果缓存无法跟踪这些关系,您将不得不自己做——这会使您的应用程序更加麻烦和复杂。

结论

因此,当 SOA 应用程序使用的数据保存在对频繁事务不可扩展的存储中时,它就无法有效扩展。 这就是分布式缓存的地方 NCache 真的很有帮助。 在企业环境中,如果不使用真正的分布式缓存基础架构,基于 SOA 的应用程序环境就无法真正扩展。 传统的数据库服务器也在不断改进,但没有分布式缓存,服务应用程序无法满足当今复杂应用程序环境中对可扩展性的爆炸式需求。


作者:伊克巴尔·汗为 Alachisoft ,一家领先的软件公司,提供 .NET 和 Java 分布式缓存、O/R 映射和 SharePoint 存储优化解决方案。 你可以联系他 伊克巴尔@alachisoft .

联系我们

联系电话
©版权所有 Alachisoft 2002 - 版权所有。 NCache 是 Diyatech Corp. 的注册商标。