Должен ли я использовать сеанс или кэш в этом сценарии? Или что-то другое?

Мне нужно создать механизм для хранения и чтения настроек (контролирует значения и настройки по умолчанию) для каждого пользователя. У меня есть проблема, связанная с сетевым трафиком, поскольку к базе данных можно получить доступ через Интернет, а сервер приложений иногда подключен к плохому интернет-соединению со скоростью 512 Кбит / с.

Мое приложение может иметь около 50 пользователей одновременно, и каждая страница / форма может содержать до 50 элементов (предпочтений). Количество страниц составляет около 80.

Итак, с точки зрения производительности, что я должен выбрать, чтобы уменьшить сетевой трафик? Сессия или кеш?

ОБНОВИТЬ

Я создал две страницы с примерами, одна с использованием кэша, а другая с использованием сессии.

Нагрузочный тест 90 пользователей

Хранимый контент 1000 элементов по 20 символов на значение каждого элемента

Вот результаты каждого теста:

MemoryCache 330 725 246 выделенных байтов

Функции, выделяющие большую часть памяти

 Имя Байт%
System.Runtime.Caching.MemoryCache.Set(строка, объект, класс System.Runtime.Caching.CacheItemPolicy, строка)   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(строка, строка []) 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, у меня могут быть разные решения для каждой платформы.

2 ответа

Оба на самом деле одинаковы, они находятся в памяти... Если вы используете сеанс БД и у вас плохое соединение, то вам следует использовать кеш, если есть, загружать из БД, если нет, а затем кешировать.

Я бы посчитал сессию механизмом кеширования, в отличие от других, он просто специфичен для конкретной сессии браузера. Мой подход будет учитывать следующие вопросы.

  1. Сбалансирована ли загрузка этого сайта? Если это так, использование сеанса вызовет постоянные сеансы, что может вызвать проблемы, если вы отключите сервер.

  2. Эти данные специфичны для пользователя? Если это так, сеанс является простым способом разделения данных без большого количества манипуляций с ключами. Он также имеет то преимущество, что по истечении времени ожидания сеанса пользователя он автоматически очищается. Если это не так, я бы рекомендовал использовать функцию MemoryCache с добавлением.NET 4.0. Поддерживает истечение срока.

  3. Как этот кеш устареет? Если пользователь A может изменить данные, кэшированные для пользователя B, теперь вы отправляете грязные данные в кэш сеанса. Это подсказывает механизм общего кэша.

Изменить: После ответа на эти вопросы вы сможете решить, какой тип механизма кэширования подходит для вашей ситуации. Затем вы можете оценить это подмножество для производительности.

Другие вопросы по тегам