如何实现异步缓存

本文关键字:异步 缓存 实现 何实现 | 更新日期: 2023-09-27 18:15:43

我们使用以下模式来处理asp.net应用程序的通用对象缓存。

private object SystemConfigurationCacheLock = new object();
public SystemConfiguration SystemConfiguration
{
    get
    {
        if (HttpContext.Current.Cache["SystemConfiguration"] == null)
            lock (SystemConfigurationCacheLock)
            {
                if (HttpContext.Current.Cache["SystemConfiguration"] == null)
                    HttpContext.Current.Cache.Insert("SystemConfiguration", GetSystemConfiguration(), null, DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration, new CacheItemUpdateCallback(SystemConfigurationCacheItemUpdateCallback));
            }
        return HttpContext.Current.Cache["SystemConfiguration"] as SystemConfiguration;
    }
}
private void SystemConfigurationCacheItemUpdateCallback(string key, CacheItemUpdateReason reason, out object expensiveObject, out CacheDependency dependency, out DateTime absoluteExpiration, out TimeSpan slidingExpiration)
{
    dependency = null;
    absoluteExpiration = DateTime.Now.AddMinutes(1);
    slidingExpiration = Cache.NoSlidingExpiration;
    expensiveObject = GetSystemConfiguration();
}
private SystemConfiguration GetSystemConfiguration()
{
    //Load system configuration
} 

问题是,当负载(~100,000用户)时,我们看到TTFB的巨大跳跃,因为CacheItemUpdateCallback阻止所有其他线程执行,直到它完成从数据库中刷新缓存。

所以我认为我们需要的是一个解决方案,当第一个线程在缓存过期后试图访问它时,一个异步线程被触发来更新缓存,但仍然允许所有其他执行线程从旧的缓存中读取,直到它成功更新。

.NET框架中是否有内置的东西可以本地处理我所要求的内容,或者我必须从头开始编写?

HttpContext.Current.Cache的使用是偶然的,并不一定是必要的,因为我们在单例中使用私有成员来保存缓存的数据没有问题。

请不要评论缓存时间,SPROC效率,为什么我们要缓存等,因为这是不相关的。谢谢!

如何实现异步缓存

AppFabric可能很适合您正在寻找的内容。

http://msdn.microsoft.com/en-us/windowsserver/ee695849

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

所以经过几个小时的调查发现,问题不是CacheItemUpdateCallback阻塞其他线程,因为我最初认为,事实上,它确实是我想要它异步,但它是垃圾收集器停止一切清理LOH。