我正在为常用的数据库对象实现数据缓存,我在确定缓存以下场景的最佳策略时遇到了一些困难:
我有一张名为Campaigns的表,有1423条记录。广告系列包含描述目标网页的所有文本和设置。生成登录页面时,将从数据库中提取相应的Campaign。有些登陆页面比其他登陆页面更受欢迎。
(输出缓存是我的下一步,因此无需对此进行评论。)
我在大声思考:
A)在服务器启动时将所有广告系列预先加载到字典中并将其放入缓存中。
我已经计算出这需要大约3.8 MB的服务器内存(OK),并且在首页视图上花费大约8秒钟(OK),并且当前的广告系列数量。唯一的问题是这不能很好地扩展。明天我可能会有10倍的广告系列。此外,我们还需要每天更新和添加新广告系列,并且每次都删除整个广告系列缓存似乎有点矫枉过正。
这很好的部分是所有广告系列都是全部缓存的,因此在访问未访问的目标网页时(例如搜索引擎)没有启动时间。
B)延迟加载:使用“广告系列。[id]”等密钥单独缓存每个广告系列。
这样可以很容易地杀死或添加个性化广告系列,并且我可以使用Sliding功能(如SlidingExpiration)来减少使用较少的广告系列。唯一的问题是,当搜索引擎访问一个很少访问的页面时,就是加载广告系列的时候。另一个问题是Cache上堆满了大量密钥。
C)懒惰加载到字典中与B)相同的bennefins和缓存不会被大量的键混乱,但不能使用缓存功能,如果内存紧张,整个字典将被转储。
你怎么看?我倾向于B)。此外,我还有一个场景,我需要通过id或代码(字符串)来获取广告系列。
以下内容:
Campaigns campaign = //Get campaign from database:
Cache["Campaigns.Id."+campaign.Id.ToString()] = campaign; //Id is Guid
Cache["Campaigns.Code."+campaigns.Code] = campaign;
这会花费我两倍的内存还是仅用于另一个索引参考?
答案 0 :(得分:4)
嗯,在我的头顶,我会看看缓存分组项目(类似于你的B想法),但是对它们进行超时。这意味着很少使用的项目将缓存,但最终会刷新。超时应与正常使用频率相关。例如,如果一个正常的广告系列每小时被点击10次,那么暂停的时间可能很短,也许是5-10分钟。
ASP.NET Cache内置了这个超时内容:
http://quickstarts.asp.net/QuickStartv20/aspnet/doc/caching/data.aspx
内存便宜,但仍需维护。作为首次实现,我认为基本的超时设置并不是一个糟糕的开始。这将需要监视,如任何缓存实现,以查看它是否有助于或阻碍您的使用模式。
我不会像每个项目一样精确地延迟加载。用法应该显示常用项目,或者您可以选择批次(前10名,前20名等)。智能地选择常用项目和常见项目组将有助于提高缓存的健康状况(不是很多过时的项目,没有太多的流失等)。
至于整体内存使用情况,我认为ASP.NET Cache可以配置为限制采用的字节数:
http://msdn.microsoft.com/en-us/library/ms228248.aspx
所以你不必太担心这个。