为 asp.net 网站缓存大对象

Posted

技术标签:

【中文标题】为 asp.net 网站缓存大对象【英文标题】:Caching large objects for asp.net web site 【发布时间】:2012-04-08 12:27:20 【问题描述】:

我们通过查询我们的 sql 服务器以获取以 xml 形式返回的数据,然后使用 xslt 处理以创建最终输出,从而在我们的 Web 应用程序中生成报告。 作为加快系统速度的一种方式,我们从返回的 sql xml 中删除了所有静态信息,并缓存了一个包含所有静态信息的大型 XDocument。在执行 xsl 转换之前,我们将带有静态信息的 XDocument 附加到来自 sql server 的 xml 的末尾。静态 XDocument 大约 50Meg,从 sql server 构建需要很多秒。

我们的问题是,一旦我们开始缓存这些大型 XDoc 中的一些,我们就达到了缓存私有字节大小的限制,并且缓存被清除了。当人们在运行报表时,重建这些 XDocuments 太费时了。我没有尝试将这些 XDocs 保存到物理文件,因为每天不断发生的每个报告运行都需要它们。

我曾考虑安装 AppFabric Cache,但我不确定在其中存储 5 到 10 个这样的大型项目是否是个好主意。

有什么想法吗?如果我在 Web 服务器上安装更多内存,它会自动用于 asp.net 以获得更大的缓存吗?我尝试在将数据存储到缓存之前对其进行压缩(缩小了 5 倍),但解压缩并重新解析 XDocument 会降低服务器速度。

【问题讨论】:

为什么不在数据库上使用简单的自定义缓存/或将它们保存为磁盘上的文件(更好)并让这些文件使用处理程序从用户那里下载。 @Aristos 用户不下载静态数据,它与来自sql server的xml结合,然后通过xslt处理创建报告输出。我可以将数据保存在磁盘上,但是我需要通过 XDocument.Load() 为每个报告重新加载它。认为必须有更快的方法。 使用像code.google.com/p/protobuf-net这样的真正快速序列化类将最终 XDocument.Load() 的序列化版本保存到磁盘 @Aristos 如果您将您的评论作为答案转发,我可以将其标记为我要使用的答案! 【参考方案1】:

最后,只需将其按原样保存到文件中,然后按原样重新加载它,因为它已准备好序列化。

protobuf-net 超级快速和轻便,我已经对其进行了测试和使用,但它没有任何好处,因为它已经序列化了。

【讨论】:

刚刚收到 Marc Gravell 的回复,他说 protobuf-net 不是序列化 XML 的好解决方案,因为它只会将其存储为字符串。基本上,不比 XDocument.Save() 好。 @Wavel 哦,你说得对,它已经准备好了 XML,我没想到......嗯,我改变了答案。【参考方案2】:

您可以将 xml 对象序列化为二进制格式,并使用 varbinary(max) 将其存储在数据库中。不确定它的性能,但可能值得一试,因为实施它不会花费很长时间。

您可能想要解决的其他问题是第一个访问报告的用户的性能损失。为了避免这种情况,您可以预先生成报告,以便为每个人缓存它们。

【讨论】:

如果我将 xml 序列化到 sql server 上,那么我有点回到原点,返回的 xml 在一个大 xml 中同时包含用户数据和静态数据。我无法预先生成报告,因为它们是用户设计的临时报告。用户数据也在不断变化。 我误会你了,我认为报告有点有限,每个人都得到了相同的结果,这就是你想使用缓存的原因

以上是关于为 asp.net 网站缓存大对象的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET 和输出缓存 - 如何查看它是不是正常工作?

ASP.NET Core中如何使用缓存

ASP.NET 输出缓存在 IIS7.5 上不起作用

在 asp.net 中创建静态对象列表

跨负载平衡服务器的选择性缓存清除 (ASP.Net)

使用内存缓存时 Asp.Net MVC 中的 InvalidOperationException