我需要在ASP.NET Web API中缓存有关用户角色的信息。我决定使用System.Web.Helpers.WebCache
类。角色是纯字符串,大约40个字符长。每个用户可能具有1-10个角色。
我正在考虑两种方法:
WebCache.Set(UserID, List<String>).
使用用户ID作为键,并将角色列表(字符串)存储为值。它易于检索。 问题:
500 bytes
,磁盘大小为4 KB
。然后,如果我有200个用户,我将乘以200 * 500字节来计算内存使用量。是这种计算方法(如果近似封闭,我可以)吗?答案 0 :(得分:0)
我更喜欢保存单个密钥的方法,而不是将所有用户的角色保存为单个缓存对象。
以下是原因:
1)创建很简单,当用户登录时或在适当的时候,将检查缓存并为该用户创建“如果为空”,则无需遍历字典对象(或LINQ)即可到那个关键项目。
2)当用户注销或在适当的时候,缓存对象将被完全销毁,而不仅仅是从缓存中删除该特定键。
3)当多个用户试图同时访问对象时,也不需要锁定对象,并且这种情况将发生。由于对象是按用户创建的,因此没有锁定该对象的风险,也无需使用同步或互斥锁。
谢谢Praveen
答案 1 :(得分:0)
与可维护性和功能性相比,用于此类应用程序的单个字节的内存存储通常是次要的问题,这是因为用户角色通常是具有相当大的安全性问题的核心功能,并且随着项目的发展,它将变得非常重要。保证代码的可维护性和安全性很重要。
缓存应专门用于优化,因为这与相对较小的用户群(约200人)的少量数据有关,因此使这些角色的缓存更细粒度且易于重新提取会更好。 根据该库的官方文档
Microsoft system.web.helpers.webcache
通常,您永远不要指望已缓存的项目位于缓存中
并且由于我假设用户角色定义了一些相当重要的功能,因此最好将对这些角色的查询添加到您的Web API请求中,而不是将其存储在本地。
但是,如果您对使用此高速缓存一无所知,并且在该高速缓存消失后进行重新获取,则根据您的问题,选项一将是更可取的选择。
这是因为列表占用的内存较少,在这种情况下,它看起来更加简单明了,使用字典对我没有任何好处。
当数据集很大且需要速度时,字典会发光,但是对于这种情况,所有数据已经存储在内存中,并且数据集相对较小,因此字典会带来复杂性和更高的内存需求,而其他方面则不多。尽管在大多数现代设备和服务器上,这两种情况下的内存使用情况听起来都是微不足道的。
鉴于您需要用户查找角色,字典可能听起来很引人注目,但WebCache类似乎已经具有这种功能,因此其他字典就失去了吸引力
答案 2 :(得分:0)
Q1:不知道Cache项的实际用法,很难得出结论。尽管如此,我认为所有这些都归结为这些项目的垃圾邮件设计。如果要在一定时期内一次全部淘汰它们,然后查询一组新数据,则将ConcurrentDictionary存储到WebCache中可以容纳用户和角色,这是一个更容易管理的解决方案。
否则,如果您要根据特定事件分别退出每个条目,那么采用一种方法似乎是一个很简单的答案。请注意,如果选择方法二,请使用ConcurrentDictionary而不是Dictionary,因为后者不是线程安全的。
Q2:WebCache基本上是IEnumerable>,因此它存储键字符串和每个值的存储位置,以及对象的元数据。另一方面,ConcurrentDictionary / Dictionary存储键字符串的哈希码和每个值的存储位置。尽管每个键的byte []长度都很小,但其哈希码可能比字符串的大小稍大。否则,HashCodes的大小是非常可预测的,并且相当薄(在我的测试中约为10个字节)。每次添加条目时,整个集合的大小大约增加30个字节。当然,该数字不包括该值的实际大小,因为它与集合无关。
您可以使用以下方法计算字符串的大小:
System.Text.Encoding.UTF8.GetByteCount(key);
您可能还会发现编写代码以达到对象大小很有用:
static long GetSizeOfObject(object obj)
{
using (var stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, obj);
return stream.Length;
}
}
答案 3 :(得分:0)
首先请确保将有抽象层,并且如果将来可以轻松更改实现。 我看不到这两种方法都使用哈希表进行搜索的任何显着差异。 但是我想第二次使用搜索两次,当它在缓存中搜索字典时以及当它在字典中搜索用户时。 我还要推荐
列表项
不要忘记 在更新用户角色时清除缓存记录
答案 4 :(得分:0)
您不需要选项2,选项1就足够了,因为您只需要key,list<string>
。
在使用缓存之前通常需要考虑的几点:-
缓存有其优点和缺点,在您的场景中,您已经完成了有效负载分析,因此我看不到选项1的任何问题。