【发布时间】:2011-07-31 12:40:02
【问题描述】:
我有一个搜索功能相当慢的 ASP.NET 站点,我想通过使用查询作为缓存键将结果添加到缓存一小时来提高性能:
using System;
using System.Web;
using System.Web.Caching;
public class Search
{
private static object _cacheLock = new object();
public static string DoSearch(string query)
{
string results = "";
if (HttpContext.Current.Cache[query] == null)
{
lock (_cacheLock)
{
if (HttpContext.Current.Cache[query] == null)
{
results = GetResultsFromSlowDb(query);
HttpContext.Current.Cache.Add(query, results, null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
}
else
{
results = HttpContext.Current.Cache[query].ToString();
}
}
}
else
{
results = HttpContext.Current.Cache[query].ToString();
}
return results;
}
private static string GetResultsFromSlowDb(string query)
{
return "Hello World!";
}
}
假设访问者 A 进行了搜索。缓存为空,设置锁并从数据库请求结果。现在访问者 B 带来了不同的搜索:访问者 B 不是必须等待访问者 A 的搜索完成吗?我真正想要的是让 B 立即调用数据库,因为结果会有所不同,并且数据库可以处理多个请求——我只是不想重复昂贵的不必要的查询。
对于这种情况,正确的方法是什么?
【问题讨论】:
-
查询真的太昂贵和/或您的网站太忙以至于您无法负担每小时一次的重复查询吗? (只有当且仅当缓存过期后,两个或多个查询几乎同时命中您的方法时,才会出现这种情况。)
-
如果你的数据库不支持多读,可以实现一个消息查询,DB服务A,然后DB服务B……服务的时候,检查缓存。
-
@LukeH,在那个特定的数据库中发生了很多事情,所以我们可以减轻任何负载都是值得的。
-
只有一台网络服务器吗?如果没有,您可以使用分布式缓存来获得更大的效果。
-
@Chris,到目前为止只有一个网络服务器。
标签: c# .net asp.net caching locking