Состояние сеанса ASP.NET MVC с использованием разбиения состояния, MongoDB или Memcached или ...? - PullRequest
11 голосов
/ 29 мая 2011

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

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

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

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

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

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

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

Режим StateServer: может использоваться в веб-ферме, но если сервер выходит из строя, я теряю все свои сеансы. (Устранено)

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

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

Режим 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 Ответ

31 голосов
/ 29 мая 2011

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

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

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

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

Посмотрите на мои предложения по производительности от: http://omaralzabir.com/tag/performance/

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

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

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

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

Надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...