【问题标题】:Efficiency of persistence methods for large asp.net cache store大型 asp.net 缓存存储的持久性方法的效率
【发布时间】:2010-09-29 17:48:04
【问题描述】:

好奇是否有人对哪种方法更适合 asp.net 缓存有意见。选项一,缓存中较复杂的项目较少,或较不复杂的项目较多。

为了便于讨论,假设我的网站有 SalesPerson 和 Customer 对象。这些是非常简单的类,但我不想与数据库闲聊,所以我想将它们延迟加载到缓存中,并在我进行更改时使它们从缓存中失效——很简单。

选项 1 创建字典并缓存整个字典。当我需要从缓存中加载 SalesPerson 的实例时,我会从 Dictionary 中取出并针对 Dictionary 执行正常的键查找。

选项 2 为每一项的key加上前缀,直接存放在asp.net缓存中。例如,缓存中的每个 SalesPerson 实例都将使用前缀加上该对象的键的组合,因此它可能看起来像 sp_[guid] 并存储在 asp.net 缓存中,缓存中还有带有像 cust_[guid] 这样的键。

我对选项二的担心之一是条目的数量会变得非常大,在销售人员、客户和十几个其他类别之间,我可能在缓存中有 25,000 个项目,并且对字符串资源之类的东西进行高度重复的查找我在几个地方使用可能会付出代价,而代码会在缓存的密钥集合中查找它以在其他 25K 中找到它。

我确信在某些时候,在缓存中存储太多项目会导致收益递减,但我很好奇关于这些问题的意见。

【问题讨论】:

    标签: c# asp.net caching


    【解决方案1】:

    您最好在缓存中创建更多、更小的项目,而不是创建更少、更大的项目。原因如下:

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

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

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

    【讨论】:

      【解决方案2】:

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

      我会关心任何能让你的工作更轻松的事情。如果让缓存更有条理将使您的应用程序更易于理解、调试、扩展和维护,那么我会这样做。如果它使这些事情变得更复杂,那么我不会这样做。

      正如 nullvoid 所提到的,这一切都假设您已经探索了缓存的更大影响,其中涉及衡量性能增益与性能损失。您正在谈论存储大量对象,这意味着大量缓存流量。我只会在缓存中存储一​​些你可以衡量这样做的性能提升。

      【讨论】:

        【解决方案3】:

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

        【讨论】:

          【解决方案4】:

          我假设您已经考虑了来自多个用户的数据更改的所有影响,以及在处理冲突数据方面这将如何影响缓存数据。缓存实际上只适用于相对静态的数据。

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

          从维护的角度来看,这也是一种更好的方法,因为您可以创建一个强类型对象来表示数据并使用序列化在缓存和您的销售人员/客户对象之间进行转换。

          【讨论】:

          • System.Web.Caching 命名空间中的 ASP.NET 缓存没有序列化,我不认为。这是它相对于 Session/Application/ViewState/etc 的主要优势之一。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-03-12
          • 1970-01-01
          • 2017-07-25
          • 1970-01-01
          • 2012-03-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多