我必须创建一种机制来存储和读取每个用户的首选项(控制默认值和设置)。我遇到了与网络流量有关的问题,因为数据库可以通过互联网访问,而应用服务器有时连接到差的512Kbps互联网连接。
我的应用程序可以有大约50个并发用户,每个页面/表单最多可以有50个项目(首选项)。页数大约是80。
因此,考虑到性能方面的观点,我应该选择哪种方式来减少网络流量?会话或缓存?
我创建了两个示例页面,一个使用缓存,另一个使用会话。
加载测试 90位用户
存储内容 1000个元素 每个元素的值为20个字符
以下是每个测试用例的结果:
的MemoryCache 分配了330,725,246个总字节数
分配大部分内存的功能
Name Bytes % System.Runtime.Caching.MemoryCache.Set(string,object,class System.Runtime.Caching.CacheItemPolicy,string) 34,74 System.Web.UI.Page.ProcessRequest(class System.Web.HttpContext) 18,39 System.String.Concat(string,string) 12,65 System.String.Join(string,string[]) 5,31 System.Collections.Generic.Dictionary`2.Add(!0,!1) 4,42
源代码:
protected void Page_Load(object sender, EventArgs e)
{
outputPanel.Text = String.Join(System.Environment.NewLine, ReadEverything().ToArray());
}
private IEnumerable<String> ReadEverything()
{
for (int i = 0; i < 1000; i++)
{
yield return ReadFromCache(i);
}
}
private string ReadFromCache(int p)
{
String saida = String.Empty;
ObjectCache cache = MemoryCache.Default;
Dictionary<int, string> cachedItems = cache["user" + Session.SessionID] as Dictionary<int, string>;
if (cachedItems == null)
{
cachedItems = new Dictionary<int, string>();
}
if (!cachedItems.TryGetValue(p, out saida))
{
saida = Util.RandomString(20);
cachedItems.Add(p, saida);
CacheItemPolicy policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(30);
cache.Set("user" + Session.SessionID, cachedItems, policy);
}
return saida;
}
会话 分配的总字节数为111,625,747
分配大部分内存的功能
Name Bytes % System.Web.UI.Page.ProcessRequest(class System.Web.HttpContext) 55,19 System.String.Join(string,string[]) 15,93 System.Collections.Generic.Dictionary`2.Add(!0,!1) 6,00 System.Text.StringBuilder.Append(char) 5,93 System.Linq.Enumerable.ToArray(class System.Collections.Generic.IEnumerable`1) 4,46
源代码:
protected void Page_Load(object sender, EventArgs e)
{
outputPanel.Text = String.Join(System.Environment.NewLine, ReadEverything().ToArray());
}
private IEnumerable<String> ReadEverything()
{
for (int i = 0; i < 1000; i++)
{
yield return ReadFromSession(i);
}
}
private string ReadFromSession(int p)
{
String saida = String.Empty;
Dictionary<int, string> cachedItems = Session["cachedItems"] as Dictionary<int, string>;
if (cachedItems == null)
{
cachedItems = new Dictionary<int, string>();
}
if (!cachedItems.TryGetValue(p, out saida))
{
saida = Util.RandomString(20);
cachedItems.Add(p, saida);
Session["cachedItems"] = cachedItems;
}
return saida;
}
我忘了提到我正在创建一个使用ASP.Net和WPF项目的解决方案,但是,如果Session远比MemoryCache选项好,我可以为每个平台提供不同的解决方案。
答案 0 :(得分:0)
两者都是相同的,它们在内存中...如果你使用的是数据库会话并且连接不良,那么你应该使用缓存(如果存在),如果没有则加载,然后缓存。
答案 1 :(得分:0)
我认为会话是一种缓存机制,与其他会话不同,它只针对特定的浏览器会话。我的方法会考虑以下问题。
此网站负载均衡吗?如果是,则使用会话将强制执行持久会话,如果您关闭服务器可能会导致问题。
此数据用户是否具体?如果是,会话是一种简单的方法来隔离数据而无需大量的键操作。它还具有以下优点:当用户的会话超时时,它会自动清理。如果不是,我建议使用添加了.NET 4.0的MemoryCache功能。它支持到期。
此缓存将如何过时?如果用户A可以修改为用户B缓存的数据,那么您现在正在使用会话缓存提供脏数据。这会提示共享缓存机制。
编辑:一旦回答了这些问题,您就应该能够确定哪种类型的缓存机制适合您的情况。然后,您可以评估该子集的性能。