说我有一组用户。每个用户都有 User_ID ,用户名和 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缓存不支持区域,标记或通知。
答案 0 :(得分:4)
为了它的价值,我倾向于不想在多个密钥下缓存同一个对象,因为如果您以后需要更新或删除该记录,则必须记住更新/删除所有可能的密钥它本可以使用。
答案 1 :(得分:2)
过去,我已将项目分别添加到缓存中,从缓存中删除记录的主键。然后,在需要的地方,我维护了一个字典对象,它让我快速查找以根据其他值找到主键。当我需要这个时,我会创建一个自定义集合类,它包含了维护字典的所有逻辑,查找从缓存中过期的记录,搜索从未添加到缓存中的记录,提供用于检索项目的访问器它们的各种值等等。这个结构使得每个数据项都可以单独到期,而不需要使用它的其余部分,但是我的字典仍然会保留哪些键属于哪个次要值的列表,所以我可以恢复过期无论使用哪个访问者来请求它都很容易。
不能说这一定是最好的方法,但它似乎可以很好地减少数据存储的访问,而不会让app服务器陷入困境,因为它在内存中挤得太多了。当我开发这种技术时,我正在使用标准的ASP.NET和SQL后端,但我看不出有什么原因导致它无法转换为云环境。
答案 2 :(得分:1)
在这种情况下,我很想做类似的事情:
List<User> users = [list of users]
Dictionary<string,int> userIDLookup = ...
Dictionary<string,int> tennantIDLookup = ...
Dictionary<string,int> usernameLookup = ...
这具有使用多个查找字典缓存单个对象的好处,这些查找字典为List提供索引。您可以将其封装在一些不错的方法中,如GetUserFromName(字符串用户名)...等...,以便在代码中更容易使用。也许所有这些都放在一个UserCache类中,这样你就可以实例化缓存并在其上调用查找方法。