我正在编写一个Web应用程序,它不断从数据库中检索XML“组件”,然后使用XSLT将它们转换为XHTML。其中一些转换经常发生(例如,“侧边栏导航”组件针对相同的XML发出,并在每个具有该侧边栏的页面上执行相同的XSL转换),因此我开始实施一些缓存以加快速度。
在我当前的解决方案中,在每个组件尝试执行转换之前,组件会检查静态CacheManager
对象,以查看转换后的XML的缓存版本是否存在。如果是,则组件输出。如果没有,组件将执行转换,然后将转换后的XML与CacheManager
对象一起存储。
CacheManager
对象保留缓存的转换XML的内存存储(确切地说,在Dictionary
中)。在我的本地开发环境中,这种工作非常好,但我认为这可能不是一个非常可扩展的解决方案。
将这些数据存储在内存中的潜在缺点是什么?我是否需要限制我可以存储在这样的内存数据结构中的数据量?我是否应该使用不同的数据存储来完成这种类型的缓存?
答案 0 :(得分:4)
正如您所怀疑的那样,明显的缺点是缓存可能会占用大量内存。您可能希望实现一个系统,当内存压力上升时,很少使用的项目会从缓存中“过期”。微软的Caching Application Block实现了你需要的所有东西,开箱即用。
您可能遇到的另一个潜在(虽然不太可能)问题是挖掘缓存以找到所需内容的成本。在某些时候,可以更快地继续生成您需要的内容而不是查看缓存。我们在至少一个与非常大的缓存和非常便宜的操作相关的精确场景中遇到了这种情况。这不太可能,但可能会发生。
答案 1 :(得分:1)
您应该明确地寻找通用的chache实现。我不做C#,所以我不知道你的语言有什么解决方案。在Java中,我会推荐EHCache。
一开始看缓存要困难得多。这就是为什么依靠别人的工作可能是一个好主意。您在某些时候遇到的一些问题是并发,缓存失效,生存时间,阻塞缓存,缓存管理(统计,清除缓存......),溢出到磁盘,分布式缓存,......
监控缓存是必须的。你需要看看你实施的缓存策略是否真的做得很好(缓存命中/缓存未命中,使用的缓存百分比,......)你应该在多个区域划分你的缓存,以便更好地监控缓存的使用。
作为旁注,只要在转换后缓存XML,就应该存储其String表示(而不是对象树)。这是缓存之后要做的少一个转换,因为你可能无论如何都要将它输出为String。并且String表示很可能会占用更少的空间(但是一如既往地衡量它,不要接受我的话)。
答案 2 :(得分:1)
您可以执行缓存,但只在字典中保留引用值(uri)并将实际转换的XML存储在磁盘上。这可能比从数据库中检索值并再次进行转换要快,比将所有值全部存储在内存中要慢,但是首先解决了将所有这些缓存数据都放在内存中的问题。这也可以允许转换后的XML文档通过循环/重置生存,但是您必须重建字典,并且还必须考虑需要从磁盘缓存中清除的“过期”文档。
只是一个想法..