0

我必须创建一种机制来存储和读取每个用户的首选项(控制默认值和设置)。我有一个与网络流量有关的问题,因为可以通过 Internet 访问数据库,并且应用程序服务器有时连接到较差的 512Kbps Internet 连接。

我的应用程序可以同时拥有大约 50 个用户,每个页面/表单最多可以有 50 个项目(首选项)。页数约为 80 页。

那么,从性能角度考虑,我应该选择哪个来减少网络流量?会话还是缓存?

更新

我创建了两个示例页面,一个使用缓存,另一个使用会话。

负载测试 90 个用户

存储内容 1000 个元素 每个元素的值 20 个字符

以下是每个测试用例的结果:

MemoryCache 分配的总字节数为 330,725,246

分配最多内存的函数

名称字节 %
System.Runtime.Caching.MemoryCache.Set(string,object,class System.Runtime.Caching.CacheItemPolicy,string) 34,74
System.Web.UI.Page.ProcessRequest(类 System.Web.HttpContext)18,39
System.String.Concat(字符串,字符串)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

分配最多内存的函数

名称字节 %
System.Web.UI.Page.ProcessRequest(类 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(类 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 选项好得多,我可以为每个平台提供不同的解决方案。

4

2 回答 2

0

我认为会话是一种缓存机制,与其他机制不同,它只是特定于特定的浏览器会话。我的方法将考虑以下问题。

  1. 这个网站负载均衡吗?如果是这样,使用会话将强制使用持久会话,如果您关闭服务器,可能会导致问题。

  2. 此数据用户是否特定?如果是,会话是一种无需大量密钥操作即可分离数据的简单方法。它还有一个好处是,当用户的会话超时时,它会自动被清理。如果不是,我建议使用添加了 .NET 4.0 的 MemoryCache 功能。它支持过期。

  3. 这个缓存怎么会过时?如果用户 A 可以修改为用户 B 缓存的数据,那么您现在正在使用会话缓存提供脏数据。这提示了共享缓存机制。

编辑:一旦回答了这些问题,您应该能够决定哪种类型的缓存机制适合您的情况。然后,您可以评估该子集的性能。

于 2014-08-07T18:58:26.523 回答
0

两者实际上是相同的,它们都在内存中...如果您正在使用数据库会话并且连接不佳,那么您应该使用缓存(如果存在),如果没有则从数据库加载然后缓存。

于 2014-08-07T18:54:03.140 回答