Состояние сеанса ASP.NET MVC с использованием разбиения состояний, MongoDB или Memcached или...?

Моя команда в настоящее время строит новое приложение SaaS для нашей компании (Amilia.com). Мы находимся в выпуске "alpha", и приложение было создано для развертывания на веб-ферме.

Для нашего провайдера сеансов мы используем режим Sql Server (в DEV и TEST) и, похоже, не "масштабируемы", поэтому мы ищем лучшее решение для обработки сеансов в asp.net(mvc3 в нашем случае). В настоящее время мы используем Sql Server, но мы хотели бы переключиться на другую систему из-за стоимости лицензии.

Мы нацеливаем 20 000 [EDITED, было 100k до] одновременных пользователей. В сеансе мы храним GUID, строку и объект Cart (мы стараемся как можно меньше сохранить этот объект, который позволяет нам сохранять 3 запроса при каждом запросе).

Вот различные решения, которые я нашел:

Встроенные решения ASP.NET:

Нет сеанса: невозможно в нашем случае (исключено)

Режим In-Proc: не может использоваться в webfarm. (Устранено)

Режим StateServer: может использоваться в webfarm, но если сервер опускается, я теряю все свои сеансы. (Устранено)

Режим StateServer с PartitionResolver с использованием нескольких серверов (http://msdn.microsoft.com/en-ca/magazine/cc163730.aspx#S8) Если я правильно понял, если один из этих серверов опустится, только часть моих пользователей будет теряют свою сессию.

Режим SqlServer: может использоваться в webfarm, если сервер опускается, я могу восстановить свои сеансы, но процесс довольно медленный. Более того, эта база данных становится узким местом в случае большой нагрузки.

Режим SqlServer с PartitionResolver с использованием нескольких серверов (http://www.bulletproofideas.net/2011/01/true-scale-out-model-for-aspnet-session.html). Если один из этих серверов опускается, только часть моих пользователей потеряет сессию. Если пользователь ничего не делал между простоями, он восстановит свою предыдущую сессию, иначе он будет перенаправлен на экран ввода.

Пользовательские решения:

Используйте MongoDB как хранилище сеансов (http://www.adathedev.co.uk/2011/05/mongodb-aspnet-session-state-store.html). Это хороший компромисс, но мои знания в nosql довольно рудиментарны, поэтому я не вижу недостатков.

Использование Memcached: проблема будет такой же, как в режиме StateServer, и если сервер memcached опустится, все мои сеансы будут потеряны. Кроме того, я думаю, что Memcached не предназначен для хранения состояния сеанса?

Используйте распределенный memcached, такой как ScaleOut (http://highscalability.com/product-scaleout-stateserver-memcached-steroids): это лучшее решение, но оно стоит денег.

Использовать repcached и memcached (http://repcached.lab.klab.org/), я никогда не видел реализации этого решения.

Мы могли бы легко перейти к Ms Azure и использовать предоставленные им инструменты, но у нас есть только одно приложение, поэтому, если Microsoft удваивает цену, мы сразу удваиваем стоимость нашей инфраструктуры (но это еще одна тема).

Итак, какой лучший способ или, по крайней мере, ваше мнение об этом?

Ответ 1

Сеанс SQL Server довольно хорош. Поскольку у вас уже есть база данных SQL Server для хранения первичных данных, вы можете просто создать другую базу данных и сохранить там сеанс ASP.NET.

О масштабируемости, я бы сказал, если у вас есть 100 000 одновременных пользователей, то ваша база данных должна быть больше 10 миллионов или более. Вы должны сделать некоторые практические оценки, чтобы увидеть, сколько времени потребуется для достижения такой одновременной нагрузки пользователя. В моем предыдущем запуске у нас было миллионы пользователей по всему миру, 24x7, но мы почти никогда не достигали 10K одновременных пользователей, хотя люди постоянно использовали наш сайт в течение нескольких часов каждый день.

Если у вас действительно есть 100 000 одновременных пользователей, стоимость лицензии будет наименьшей из ваших проблем. При правильной бизнес-модели наличие одновременных пользователей со 100 КБ означает, что у вас есть доход в год не менее 10 миллионов долларов.

Я построил myoffice.bt.com, который использует сеанс SQL Server и все первичные данные на одном экземпляре SQL Server, но в двух базах данных. Между 8:00 и 10:00 миллионы пользователей попали на наш сайт. У нас вряд ли есть проблемы с производительностью. С двухъядерным сервером, 8 ГБ оперативной памяти, вы можете с радостью запустить экземпляр SQL Server и поддерживать такую ​​нагрузку, пока вы правильно ее кодируете. Все зависит от того, как вы закодированы. Если вы следовали рекомендациям по производительности, вы можете легко масштабировать миллионы пользователей на одном сервере базы данных.

Взгляните на мои предложения по эффективности: http://omaralzabir.com/tag/performance/

Я использовал memcached-кластеры только для кэширования часто используемых данных. Никогда не использовался для сеанса по уважительным причинам. Было несколько случаев, когда сервер memcached пришлось перезагружать. Если бы мы использовали memcached для сеанса, мы потеряли бы все сеансы, хранящиеся в этом экземпляре. Поэтому я бы не рекомендовал хранить сеансы в memcached. Но опять же, насколько важно для вашего приложения поддерживать данные в сеансе? Если у вас есть корзина для покупок, то, когда пользователи добавляют продукты в корзину, она должна сохраняться в базе данных, а не в сеансе. Сессия обычно предназначена для краткосрочного хранения. Для любых транзакционных данных вы никогда не должны держать их в сеансе, а не хранить их непосредственно в реляционных таблицах.

Я всегда поддерживаю использование Session. Разработчики злоупотребляют сессией все время. Всякий раз, когда они хотят передавать данные с одной страницы на другую, они просто помещают ее в сеанс. Это приводит к плохому дизайну. Если вы действительно хотите масштабировать до 100K одновременной базы пользователей, создайте приложение, чтобы вообще не использовать сеанс. Любые транзакционные данные должны храниться в базе данных. Корзина является транзакционным объектом и, следовательно, не подходит для проведения сеанса. В какой-то момент вам нужно будет узнать, сколько тележек началось, но никогда не попадается. Таким образом, вам нужно будет хранить их в базе данных навсегда.

Помните, что сеанс, основанный на базе данных, представляет собой сериализацию, основанную на базе данных на базе данных. Подумайте очень внимательно о том, что вы сериализуете в базу данных. Вам также придется очистить его, так как Session_End не будет запускаться для сеанса на базе базы данных или, фактически, для большинства сеансов вне proc. Таким образом, по сути, вы предоставляете разработчикам возможность просто сериализовать данные в базу данных и обходить реляционную модель. Это всегда приводит к плохому кодированию.

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

Надеюсь, это поможет вам в ваших проблемах.