用于在ASP.NET应用程序中搜索结果的缓存体系结构

时间:2009-10-12 18:58:23

标签: c# asp.net caching

在ASP.NET系统中缓存昂贵搜索结果的好设计是什么?

任何想法都会受到欢迎......特别是那些不需要发明我们自己的复杂基础设施的想法。

以下是与此问题相关的一些一般要求:

  • 每个搜索结果都可以生成从零到几百个结果记录的包含
  • 每次搜索都相对昂贵且耗时耗尽(数据库为5-15秒)
  • 结果必须在显示在客户端之前进行分页,以避免用户信息过载
  • 用户希望能够在返回的结果中进行排序,过滤和搜索
  • 用户希望能够在搜索结果中的页面之间快速切换
  • 用户希望能够在任意数量的页面上选择多个项目(通过复选框)
  • 一旦搜索完成,用户预计会有相对较快的性能

我看到了一些可能的选项,用于实现缓存的位置和方式:

1。缓存在服务器上(在会话或应用缓存中),使用回发或Ajax面板来促进有效的分页,排序,过滤和搜索。

  • PROS :易于实施,来自ASP.NET基础架构的良好支持
  • 缺点:在服务器上非常繁琐,内存密集,数据可能会被缓存超过必要的时间;禁止负载平衡实践

2。在服务器上缓存(如上所述)但使用可在一段时间后移出内存的可序列化结构以减少服务器上的内存压力

  • PROS :有效使用服务器内存;能够使用负载平衡进行扩展;
  • CONS :.NET基础架构的有限支持;数据结构发生变化时可能会很脆弱;在数据库上放置额外的负载;显着更复杂

第3。在客户端上缓存(使用JSON或XML序列化),使用客户端Javascript对页面进行分页,排序,筛选和选择。

  • PROS :用户体验可以达到“富客户”级别;大多数浏览器本身可以处理JSON / XML - 存在用于操作的体面库(例如jQuery)
  • 缺点:初始请求可能需要很长时间才能下载;客户机上占用大量内存;将需要在某种程度上手工制作的Javascript来实现

4。使用数据的压缩/编码表示在客户端上缓存 - 在切换页面,排序,过滤和搜索时回调到服务器进行解码。

  • PROS :最大限度地减少内存对服务器的影响;只要客户需要,国家就可以生存;通过JSON / XML
  • 略微改善了客户端上的内存使用率
  • CONS :大型数据集在客户端/服务器之间来回移动;与使用JSON / XML的纯客户端缓存相比,性能较慢(由于网络I / O);实现起来要复杂得多 - 来自.NET /浏览器的有限支持

5。我没有考虑过一些替代缓存方案......

6 个答案:

答案 0 :(得分:12)

对于#1,您是否考虑过使用状态服务器(甚至SQL服务器)或共享缓存机制?来自plenty goodones choose来自Velocity,而SharedCache (FOSS)正在变得非常成熟 - 很快就会推出RTM。基于用户是否创建新搜索,访问除搜索分页之外的任何其他页面以及最后标准超时(20分钟)的缓存失效方案应该非常成功地将缓存减少到最小尺寸。

  

参考文献:

     

答案 1 :(得分:5)

如果你能够等到2010年3月,.NET 4.0会附带一个新的System.Caching.CacheProvider,它承诺了很多实现(如上所述的磁盘,内存,SQL Server / Velocity)。

有一个很好的幻灯片技术here。然而,它有点“滚动你自己”或其中很多。但是,当框架发布时,可能会有许多为Provider模型编写的封闭式和开源式提供程序。

对于你所说的六点,会出现一些问题

  • 搜索结果中包含哪些内容?只是字符串数据或与每个结果相关的大量元数据?
  • 您正在搜索的设置有多大?

您将使用多少内存将整个集存储在RAM中?或者至少拥有最受欢迎的10到100个搜索词的缓存。在第一次搜索之后,智能和缓存相关搜索可能是另一个想法。

5-15秒的结果是很长时间等待搜索所以我假设它类似于expedia.com搜索,其中查询多个源并返回大量信息。

从我有限的经验来看,客户端唯一缓存方法的最大问题是Internet Explorer 6 or 7。仅限服务器和HTML是我的首选,整个结果集在缓存中进行分页,在一段合理的时间段后到期。但是你可能已经尝试过了,看到服务器的内存被吃掉了。

答案 2 :(得分:3)

根据“替代”缓存方案提出一个想法。这不会回答您使用给定缓存架构的问题,而是回到您对搜索应用程序的原始要求。

即使/当您实现自己的缓存时,它的有效性也可能不是最佳的 - 尤其是当您的搜索索引的大小增加时。随着索引的增长,缓存命中率将降低。在某个拐点处,由于专用于搜索和缓存的资源,您的搜索实际上可能会变慢。

大多数搜索子系统都实现了自己的内部缓存架构,作为运营效率的一种手段。 Solr是一个基于Lucene构建的开源搜索系统,它维护自己的内部缓存以提供快速操作。还有其他适合您的搜索系统,它们采用类似的策略来进行结果缓存。

如果您的搜索索引保证,我建议您考虑使用单独的搜索体系结构,因为在自由文本关键字搜索基础上进行缓存是一项复杂的操作,无法有效实施。

答案 3 :(得分:1)

既然你说任何想法都是受欢迎的:

我们已经相当成功地使用企业库缓存来缓存LINQ结果中的结果集。

http://msdn.microsoft.com/en-us/library/cc467894.aspx

它支持自定义缓存过期,因此应该支持您的大部分需求(带一点自定义代码)。如果搜索隐私很重要,它还有很多后备存储,包括加密后备存储。

它功能齐全。

我的建议是#1和#3的组合

  1. 在服务器上缓存查询结果。
  2. 将结果作为整页和JSON视图提供。
  3. 缓存在客户端动态检索的每个页面,但每次页面更改时都发送REQUEST。
  4. 使用ETAG进行客户端缓存失效。

答案 4 :(得分:0)

看一下SharedCache - 它使1/2变得非常容易,并且在负载均衡系统中工作正常。免费,开源,我们已经使用它大约一年没有问题。

答案 5 :(得分:0)

在考虑您的选择时,请考虑没有用户想要翻阅数据。我们强迫它们作为试图在HTML浏览器上构建应用程序的工件,这本身就不能很好地扩展。我们已经发明了各种各样的hackery来伪造应用程序状态,但它本质上是一个破碎的模型。

因此,请考虑将其实现为Silverlight或Flash中的实际富客户端。您将无法击败该用户体验,并且缓存比常规网页中实际大得多的数据非常简单。根据预期的用户行为,您的整体带宽可以进行优化,因为到服务器的往返只会获得一个紧凑的数据集,而不是任何ASP.NET开销。