【问题标题】:Best way to cache a collection of objects. Together or as individual items?缓存对象集合的最佳方式。一起或作为单独的项目?
【发布时间】:2011-08-19 14:13:20
【问题描述】:

假设我有一组用户。每个用户都有一个User_ID、Username和Tenant_ID。

有时我需要特定 Tenant_ID 的所有用户。
有时我需要基于 User_ID" 的特定用户。
有时我需要一个基于 用户名 的用户。

我将始终将 Tenant_ID 用作查找的一部分。

为这些数据实现缓存层的理想方法是什么?
由于我正在处理多租户系统,我应该考虑哪些因素?
管理所有可能涉及的缓存键的最佳方法是什么?

选项#1:将所有用户一起存储在“Tenant_1_Users”的单个键下

这样做的问题是我将通过网络传输大量不需要的数据。如果我只需要查找特定用户,那么我需要在检索整个集合后使用 LINQ 或其他方式在代码中进行查找。

选项 #2: 在“TenantID_1_UserID_5”和“TenantID_1_Username_Jason”等不同键下复制相同的用户对象。

这里的问题是管理用户对象的所有各种键和位置。特别是如果我需要刷新特定用户,因为它已在数据库中更新。我现在需要知道可以存储它的所有可能位置。还使用更多内存,因为同一个用户可以在不同的键下。

相关:AppFabric Cache 'Design' - Caching Individual Items or Collections?
问题是 Azure AppFabric 缓存不支持区域、标签或通知。

【问题讨论】:

    标签: c# caching azure multi-tenant


    【解决方案1】:

    对于它的价值,我倾向于不希望在多个键下缓存同一个对象,因为如果您以后需要更新或删除该记录,您必须记住更新/删除所有可能的键它本来可以用的。

    【讨论】:

    • 对,这绝对是数据重复的最大问题之一。
    【解决方案2】:

    在过去,我已将项目单独添加到缓存中,将缓存从记录的主键中取出。然后,在需要的地方,我维护了一个字典对象,它可以让我快速查找基于其他值的主键。当我需要这个时,我会创建一个自定义集合类,它包含维护字典的所有逻辑,查找从缓存中过期的记录,搜索从未添加到缓存中的记录,提供用于检索项目的访问器它们的各种值等。这种结构使得每个数据项都可以单独过期而不带走集合的其余部分,但是我的字典仍然会维护哪些键属于哪些辅助值的列表,这样我就可以恢复一个过期的无论使用哪个访问器请求它,项目都很容易。

    不能说这一定是最好的方法,但它似乎可以很好地减少访问数据存储的次数,而不会使应用服务器陷入困境,因为它在内存中塞满了太多东西。当我开发这种技术时,我正在使用标准 ASP.NET 和 SQL 后端,但我看不出它无法转换到云环境的任何原因。

    【讨论】:

      【解决方案3】:

      在这种情况下,我很想这样做:

      List<User> users = [list of users]
      Dictionary<string,int> userIDLookup = ...
      Dictionary<string,int> tennantIDLookup = ...
      Dictionary<string,int> usernameLookup = ...
      

      这样做的好处是单个对象被多个查找字典缓存,这些查找字典提供了列表中的索引。您可以将其封装在一些不错的方法中,例如 GetUserFromName(string username)... 等... 以使其更易于在您的代码中使用。也许所有这些都放在一个 UserCache 类中,这样您就可以实例化缓存并在其上调用查找方法。

      【讨论】:

        猜你喜欢
        • 2010-11-05
        • 1970-01-01
        • 2021-11-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-03
        相关资源
        最近更新 更多