WCF / Silverlight / SQL DB缓存策略

时间:2009-02-20 16:23:00

标签: wcf silverlight caching

好的,我有一个相当复杂的silverlight应用程序,它从WCF服务(asp.net托管服务层)获取数据,后者又调用一个数据层来调用SQL 2005 DB中的存储过程来提取所需的数据。所以往返就是这样:

Silverlight App - > WCF服务 - >数据层 - > DB - >数据层 - > WCF服务将数据实体转换为对应的DTO(数据传输对象)或列表<> - > Silverlight App

大部分数据都是高度关系的(因此它需要存在于数据库中),但它很少会发生变化。似乎我有几个位置选择来缓存这个“半常数”数据:

  1. 我可以将其缓存在数据层中。我的数据层已经设置为使用SQLDependency类并缓存存储过程调用的结果。我认为这是或者可以是应用程序级缓存。
  2. 我可以将生成的DTO缓存在WCF服务本身的应用程序级别(或会话级别,具体取决于调用)缓存中。 2(a)我甚至可以通过将生成的DTO的XML序列化到WCF服务端的文件中来更进一步,这样我就可以(a)检查内存缓存,然后(b)检查文件缓存和(c)点击数据层
  3. 我可以在SL应用程序的客户端上执行与2(a)类似的操作。我可以使用散列(或moddate或其他东西)将数据序列化到本地隔离存储,然后只是调用来检查它。
  4. 还要补充一点:我在IIS7中托管此WCF服务并启用动态压缩,以便(通常非常大且易于压缩)XML响应得到gzip-ed。理想情况下,似乎我希望IIS缓存此gzip-ed结果以避免所有额外处理。我认为它可能已经这样做但我不确定。

    我很确定这个问题的最终答案是某种“依赖”的风格,但我很想知道其他人是如何接近这一点的。 Do X的一个很好的战术配方,用工具Y测试性能,如果需要的话,做Z就好了。

    一些链接(我将在此研究中添加此内容):

    WCF Caching Approach

6 个答案:

答案 0 :(得分:1)

如果您的用户数据很少变化且需要快速响应,那么基于本地存储的自定义机制比等待服务器往返更快速。

Dino Sposito在MSDN杂志上发表了一篇关于本地存储和缓存的有趣文章,您可以找到一种捕获程序集的方法(想象一下只需加载所需的最小程序包,然后在后台加载其余程序集,...性能火箭,你的代码更复杂:))。

正如你所说的那样,要做出平衡并做出决定。

HTH   布劳略

答案 1 :(得分:1)

我的方法是:

  1. 确定性能是否确实存在问题(我的用户是否可以接受?)
  2. 衡量每个teir的性能(数据库需要多长时间才能获得数据?服务需要多长时间才能响应数据?从服务到客户端需要多长时间?)< / LI>
  3. 根据测量结果,我会确定在哪里进行缓存。请记住,越靠近数据存储,您进行缓存越容易,但是越接近客户端进行缓存,性能提升越好(通常)。
  4. 还要记住,缓存不应该是提高性能的第一步。您还应该研究其他性能提升。存储过程是否缓慢? WCF消息中有很多开销吗?服务中是否存在一些低效的处理?我真的需要一条消息中的所有数据吗?

    HTH, 乔纳森

答案 2 :(得分:0)

我认为#2是您可维护性和架构的最佳选择。 IIS提供缓存,为什么不使用它呢?

您不希望必须从数据层引用System.Web。客户端也不是最佳选择,因为您必须编写一堆额外的代码来保持数据同步。

答案 3 :(得分:0)

当WCF在ASP.NET兼容模式下运行时,它是否甚至可用于WCF?可能最好不要依赖它并自己编写。

另一方面,看看微软的Velocity项目,看起来它会产生一种非常有趣的缓存技术,不依赖于ASP.NET。

答案 4 :(得分:0)

我们最近刚刚实施了#3,即使用独立存储的客户端缓存。

在我们的应用程序中,我们有很多下拉菜单和自定义字段,应用程序每次加载时都会从服务器获取这些字段。将这些数据移至IS确实有帮助。该应用程序现在打电话检查服务器上是否有任何更改,如果没有 - 从IS加载数据,否则(这是非常罕见的)刷新IS。

这消除了大量的WCF调用和数据传输,SL页面的加载时间更短,并且由于网络流量和数据库访问减少,应用程序通常变得更具可扩展性。

是的,涉及一些编码,但最终用户的好处至关重要。

安德鲁

答案 5 :(得分:0)

如果您使用RIA服务,那么一个简单的方法是拥有两个单独的edmx定义。一个用于缓存实体,一个用于事务性实体。

一个域上下文可以通过AddReference see引用另一个domaincontext上的实体。

可以在用户进行身份验证后立即加载缓存的实体。为简单起见,在加载缓存实体之前,不应加载事务数据。

根据缓存的大小,您可能还希望考虑将这些值序列化到本地存储。