ASP.NET MVC会话状态使用状态分区,MongoDB或Memcached还是......?

der*_*lap 11 asp.net-mvc performance session scalability

我的团队目前正在为我们公司(Amilia.com)构建一个新的SaaS应用程序.我们处于"alpha"版本,应用程序构建为部署在Web场中.

对于我们的会话提供者,我们使用的是Sql Server模式(在DEV和TEST中),它似乎不是"可扩展的",因此我们正在寻找在asp.net中处理会话的最佳解决方案(在我们的例子中是mvc3).我们目前正在使用Sql Server,但由于许可证成本,我们希望切换到其他系统.

我们的目标是20 000 [EDITED,之前是100k]并发用户.在会话中,我们存储GUID,字符串和Cart对象(我们尝试尽可能少地保留它,这个对象允许我们在每个请求时保存3个查询).

以下是我发现的不同解决方案:

ASP.NET内置解决方案:

没有会话:在我们的案例中是不可能的

进行中模式:不能在webfarm中使用.(消除)

StateServer Mode:可以在webfarm中使用,但如果服务器出现故障,我会丢失所有会话.(消除)

具有使用多个服务器的PartitionResolver的StateServer模式(http://msdn.microsoft.com/en-ca/magazine/cc163730.aspx#S8)如果我看不清楚,如果其中一个服务器出现故障,只有我的一部分用户将失去他们的会议.

SqlServer Mode:可以在webfarm中使用,如果服务器出现故障,我可以恢复我的会话,但过程非常慢.而且,该数据库在负载很重的情况下成为瓶颈.

使用多个服务器的PartitionResolver的SqlServer模式(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/),我从未见过该解决方案的实现.

我们可以轻松地访问Azure并使用它提供的工具,但我们只有一个应用程序,因此如果微软将价格提高一倍,我们会立即将基础设施成本翻倍(但这是另一个主题).

那么,最好的方法是什么,或者至少你对此有什么看法?

oaz*_*bir 31

SQL Server会话非常好.由于您已经有一个SQL Server数据库来存储主数据,因此您可以创建另一个数据库并在那里存储ASP.NET会话.

关于可扩展性,我想如果你有100,000个并发用户,那么你的用户群必须超​​过1000万或更多.您应该做一些实际的估计,看看到达这样的并发用户负载需要多长时间.在我之前的创业公司中,我们全世界有数百万用户,全天候,但我们几乎没有达到10K并发用户,即使人们每天连续使用我们的网站数小时.

如果您确实拥有100,000个并发用户,那么许可证成本将是您最不担心的.使用正确的商业模式,拥有100K并发用户意味着您每年至少有1000万美元的收入.

我已经构建了myoffice.bt.com,它使用SQL Server会话和单个SQL Server实例上的所有主数据,但是在两个数据库中.上午8点到10点之间,数百万用户访问了我们的网站.我们几乎没有任何性能问题.使用双核服务器,8 GB RAM,只要您正确编码,您就可以愉快地运行SQL Server实例并支持这样的负载.这一切都取决于你如何编码.如果您遵循了性能最佳实践,则可以轻松扩展到单个数据库服务器上的数百万用户.

请查看我的表现建议:http: //omaralzabir.com/tag/performance/

我只使用memcached群集来缓存常用数据.从来没有用过会议有充分的理由.有几次必须重新启动memcached服务器.如果我们使用memcached进行会话,我们将丢失该实例中存储的所有会话.所以,我不建议在memcached中存储会话.但话又说回来,你的应用程序在会话中维护数据有多重要?如果您有购物车,那么当用户在购物车上添加产品时,它必须保留在数据库中,而不是在会话中.会话通常用于短期存储.对于任何事务数据,您都不应该将其保留在会话中,而是将其直接存储在关系表中.

我一直支持不使用Session.开发人员一直滥用会话.每当他们想要将数据从一个页面传递到另一个页面时,他们就会将其放在Session上.这会导致糟糕的设计.如果您真的想要扩展到100K并发用户群,请将您的应用设计为根本不使用会话.任何事务数据都必须存储在数据库中.Cart是一个事务对象,因此它不适合持有Session.在某些时候,你需要知道有多少推车开始但从未放置.因此,您需要将它们永久存储在数据库中.

请记住,基于数据库的会话只不过是基于数据库的序列化.仔细考虑您要序列化到数据库中的内容.您必须清理它,因为Session_End不会触发基于数据库的会话或实际上大多数的proc会话.因此,基本上您可以让开发人员将数据序列化到数据库并绕过关系模型.它总是会导致编码错误.

通过永久关系存储,面向memcached等高性能缓存,您可以获得更好的设计来支持大量用户群.

希望这有助于您的关注.