2009-01-06 79 views
6

好奇,如果有人有意见哪种方法会更适合于asp.net缓存。选项一,缓存中较为复杂的项目或较少复杂项目。大型asp.net缓存存储的持久化方法的效率

为了便于讨论,可以想象我的网站有SalesPerson和Customer对象。这些都是非常简单的类,但我不想与数据库聊天,所以我想懒惰地将它们加载到缓存中,并在我做出更改时将它们从缓存中取消 - 这很简单。

选项1 创建词典并缓存整个字典。当我需要从缓存中加载一个SalesPerson的实例时,我得到Dictionary并对Dictionary执行一个普通的密钥查找。

选项2 将每个项目的关键字前缀并直接存储在asp.net缓存中。例如,缓存中的每个SalesPerson实例都将使用前缀加上该对象的键的组合,因此它可能看起来像sp_ [guid]并存储在asp.net缓存中,并且缓存中也存储有Customer对象键像cust_ [guid]。

我对选项二的担心之一是,在SalesPerson,Customer和十几个其他类别之间,条目数量会变得非常大,我可能在缓存中有25K项目,并且对于像字符串资源这样的高度重复查找我在几个地方使用的代码可能会支付罚款,而代码会通过缓存的密钥集合查找其中的25K。

我相信在某些时候有一个收益递减这里在缓存中存储太多的项目,但我很好奇,在这些问题上的观点。

回答

9

您最好在缓存中创建许多较小的项目,而不是创建较少的较大项目。这里是一个道理:

1)如果你的数据很小,那么在高速缓存中的项目数量会比较少,它不会有任何区别。从缓存中获取单个实体比获取字典更容易,然后从该字典中获取项目。

2)一旦数据变大,缓存可以用于智能管理数据。 HttpRuntime.Cache对象使用最近最少使用(LRU)算法来确定缓存中的哪些项目要过期。如果缓存中只有少量高度使用的项目,则此算法将无用。但是,如果缓存中有许多较小的项目,但其中有90%在任何特定时刻都未使用(非常常见的使用启发式),那么LRU算法可以确保那些看到活动用途的项目保留在缓存中同时驱逐用量较少的物品,以确保用过的物品有足够的空间。

随着应用程序的增长,能够管理缓存中的内容的重要性将变得非常重要。另外,我还没有看到在缓存中拥有数百万个密钥会导致性能下降 - 哈希表速度非常快,如果您发现问题,可以通过更改您的缓存密钥的命名约定来优化它们以便用作散列表键。

0

我会假设你已经考虑的数据来自多个用户,以及如何将影响在处理冲突的数据项缓存的数据变化的所有影响。缓存实际上只是用于相关静态数据。

从效率的角度来看,我会假设如果你正确地使用.net序列化,你将从更大型的序列化集合而不是单个基类型的数据缓存中受益。

从维护的角度来看,这也将是一个更好的办法,因为你可以创建一个强类型的对象来表示数据,并使用序列化到高速缓存和您的销售人员/客户对象之间投放。

+0

System.Web.Caching命名空间中的ASP.NET缓存不会序列化,我不这么认为。这是Session/Application/ViewState /等的主要优势之一。 – sliderhouserules 2009-01-06 06:11:12

1

ASP.NET缓存使用自己的字典,所以使用它的字典来找到你的字典来做查找来检索你的对象似乎不是最优的。字典使用哈希表,这是关于您可以做的最有效的查找。我想,使用自己的字典只会增加更多的开销。我不知道关于散列表的收益递减,但我认为这将取决于存储大小,而不是查找时间。

我会担心你的工作更容易。如果让缓存更有组织,将使您的应用更易于理解,调试,扩展和维护,那么我会这样做。如果它让这些事情变得更加复杂,那么我就不会这样做。

而且如前所述nullvoid,这是所有假设你已经探索了高速缓存的较大影响,其中涉及计量性能提升与性能损失。你说的是存储大量对象,这意味着大量的缓存流量。我只会在缓存中存储一​​些东西,你可以通过来衡量这样做的性能提升。

1

我们已经构建了一个使用缓存来存储所有资源的应用程序。该应用程序是多语言的,因此对于应用程序中的每个标签,我们至少有三个翻译。我们在第一次需要时加载(标签,文化)组合,然后仅在数据库中由管理员更改时才将其从缓存中过期。即使缓存中包含100000个项目,该场景也可以很好地工作。我们只关心配置缓存和过期策略,以便我们真正从Cache中受益。我们使用no-expiration,所以项目被缓存直到工作进程被重置或者直到该项目被故意过期。我们还注意以这种方式为关键字的值定义一个域,以便以最少的字符数唯一地标识特定文化中的标签。