是否建议在Web服务器上使用HashSet作为静态全局?

时间:2009-09-17 22:17:28

标签: c# .net asp.net .net-3.5 caching

我想创建一个“临时缓存查找”来加速我的网络服务器上的文件查找。

我现在拥有的是一个充满图像的文件夹,如果用户请求图像,我使用File.Exists(...)来检查图像是否存在。如果没有,请从其他服务器下载,无论哪种方式,都将用户重定向到它。

这个问题是很多请求一次导致File.Exists()挂起。我想保留一个快速且脏的HashSet文件名已知在本地文件夹中,这样如果用户请求一个文件,并且它存在于HashSet中,只需重定向到它而不执行File.Exists(),如果它在HashSet中不存在,请执行File.Exists()然后添加它。

我知道如果服务器重新启动,HashSet会被吹走,但我并不担心,因为使用上面的场景,它会使用最多请求的图像快速“重建”自己。

主要问题是,由于此对象将从多个用户调用,并且各种请求都将向该集添加项目,这是否会导致问题?到目前为止,我在Web服务器上使用静态全局意义的是数据库连接字符串或用于向其发送警报的电子邮件地址等。

关于竞争条件进行编辑:
是的,我在考虑竞争条件。但是在单个HashSet上甚至可能出现竞争条件?由于它只允许唯一值,第二次尝试添加值是否会失败?此时我会忽略错误并继续。

2 个答案:

答案 0 :(得分:4)

除了人们提到的竞争条件问题之外,你还要问其他一些问题。

首先,没有缓存生存期策略的缓存有一个名称 - 我们称缓存无限增长,永远不会释放其数据“内存泄漏”。他们有办法让服务器瘫痪。仔细想想你将如何知道你的缓存何时变得太大以及是时候把它扔掉了。

其次,如果他们是骗子,缓存比无用更糟糕。您的缓存声称是文件系统的加速,但您确实建议保持缓存和文件系统一致的机制是什么?假设用户访问文件,信息被缓存,然后其他一些操作删除该文件。现在缓存与事物不同步应该是抽象的;这听起来像是潜在的错误来源。下次有人访问该文件时,缓存会说它存在,即使它不再存在。

这些当然是可以解决的问题;问题不在于它们是否可以解决,而在于解决这些问题的费用是否会通过你所擅长的绩效提高来支付。

或者,你可以忽略这些问题并希望最好。例如,如果您认为运行内存泄漏或缓存不一致的成本是开展业务的成本,那么性能的提高就会付出代价。如果情况确实如此,那么故意做出明智的决定是采取一种脆弱的低成本解决方案,而不是偶然做到这一点,并在事情破裂后感到惊讶。

答案 1 :(得分:3)

这很有道理。但是,请务必注意可能的竞争条件。您可以使用ReaderWriterLockSlim class来控制从不同线程访问对象。

更新

您绝对需要适当地锁定对象,因为Add方法不是原子操作。如果同时添加两个内容,甚至可以使对象处于不一致状态。