2011-05-28 13 views
11

Mi equipo está actualmente creando una nueva aplicación SaaS para nuestra empresa (Amilia.com). Estamos en versión "alfa" y la aplicación fue desarrollada para implementarse en una granja de servidores web.ASP.NET MVC ¿Estado de sesión usando el particionamiento de estado, MongoDB o Memcached o ...?

Para nuestro proveedor de sesión, estamos utilizando el modo Sql Server (en DEV y TEST) y parece que no es "escalable", por lo tanto, estamos buscando la mejor solución para manejar sesiones en asp.net (mvc3 en nuestro caso). Actualmente estamos utilizando Sql Server, pero nos gustaría cambiar a otro sistema debido al costo de la licencia.

Nuestro objetivo es 20 000 [EDITADOS, era 100k antes] usuarios concurrentes. En sesión, almacenamos un GUID, una cadena y un objeto Cart (intentamos mantenerlo lo menos posible, este objeto nos permite guardar 3 consultas en cada solicitud).

Aquí están las diferentes soluciones que he encontrado: soluciones integradas

ASP.NET:

ninguna sesión: imposible en nuestro caso (eliminado)

en proceso Modo: puede no se usará en una webfarm. (eliminado)

Modo StateServer: se puede usar en una webfarm pero si el servidor se cae, pierdo todas mis sesiones. (eliminado)

Modo StateServer con un PartitionResolver usando varios servidores (http://msdn.microsoft.com/en-ca/magazine/cc163730.aspx#S8) Si lo entiendo bien, si uno de estos servidores falla, solo una parte de mis usuarios perderá su sesión.

Modo SqlServer: se puede utilizar en una webfarm, si el servidor se cae, puedo recuperar mis sesiones, pero el proceso es bastante lento. Además, esa base de datos se convierte en un cuello de botella en caso de carga pesada.

Modo SqlServer con PartitionResolver usando varios servidores (http://www.bulletproofideas.net/2011/01/true-scale-out-model-for-aspnet-session.html): Si uno de estos servidores falla, solo una parte de mis usuarios perderá su sesión. Si el usuario no estaba haciendo nada entre el tiempo de inactividad, recuperará su sesión anterior, de lo contrario será redirigido a la pantalla de inicio de sesión.

soluciones personalizadas:

Uso MongoDB como almacenamiento de sesión (http://www.adathedev.co.uk/2011/05/mongodb-aspnet-session-state-store.html), parece ser una buena solución de compromiso, pero mis conocimientos en nosql es bastante rudimentario, así que no puedo ver los contras.

Utilice Memcached: el problema será el mismo que el modo StateServer y si el servidor de memcached se cae, todas mis sesiones se pierden. Además, creo que Memcached no está dedicado a almacenar el estado de la sesión.

Usa memcached distribuido como ScaleOut (http://highscalability.com/product-scaleout-stateserver-memcached-steroids): parece ser la mejor solución pero cuesta dinero.

Use repcached y memcached (http://repcached.lab.klab.org/), nunca he visto una implementación de esa solución.

Podríamos ir fácilmente a la Sra. Azure y usar herramientas provistas, pero solo tenemos una aplicación, de modo que si Microsoft duplica el precio, duplicamos inmediatamente el costo de nuestra infraestructura (pero ese es otro tema).

Entonces, ¿cuál es la mejor manera o al menos cuál es tu opinión al respecto?

Respuesta

31

La sesión del Servidor SQL es bastante buena. Como ya tiene una base de datos de SQL Server para almacenar sus datos primarios, puede simplemente crear otra base de datos y almacenar allí la sesión de ASP.NET.

Acerca de la escalabilidad, diría que si tiene 100.000 usuarios concurrentes, su base de usuarios debe ser de más de 10 millones o más. Debe hacer una estimación práctica para ver realmente cuánto tiempo llevará alcanzar una carga de usuario tan concurrente. En mi inicio anterior, teníamos millones de usuarios en todo el mundo, las 24 horas, los 7 días de la semana, pero casi nunca llegamos a los 10 000 usuarios simultáneos, a pesar de que las personas usaban nuestro sitio continuamente durante horas todos los días.

Si realmente tiene 100,000 usuarios simultáneos, el costo de la licencia sería la menor de sus preocupaciones. Con el modelo de negocio correcto, tener 100K usuarios simultáneos significa que tiene al menos $ 10 millones de ingresos/año.

He creado myoffice.bt.com que utiliza la sesión de SQL Server y todos los datos primarios en una única instancia de SQL Server, pero en dos bases de datos. Entre las 8 AM y las 10 AM, millones de usuarios visitan nuestro sitio. Apenas tenemos problemas de rendimiento. Con un servidor Dual Core, 8 GB de RAM, puede ejecutar felizmente una instancia de SQL Server y admitir dicha carga siempre que la codifique correctamente. Todo depende de cómo haya codificado. Si ha seguido las mejores prácticas de rendimiento, puede escalar fácilmente a millones de usuarios en un solo servidor de base de datos.

Tome un vistazo a mis sugerencias de rendimiento a partir de: http://omaralzabir.com/tag/performance/

he utilizado racimos memcached sólo para la caché de datos de uso frecuente. Nunca se usó para la sesión por buenas razones. Ha habido varias ocasiones en las que tuvo que reiniciarse un servidor memcached. Si hubiéramos utilizado memcached para la sesión, habríamos perdido todas las sesiones almacenadas en esa instancia. Por lo tanto, no recomendaría el almacenamiento de sesiones en memcached. Pero, una vez más, ¿qué tan importante es para su aplicación mantener los datos en sesión? Si tiene un carrito de compras, a medida que los usuarios agregan productos en el carro, debe persistir en la base de datos, no en la sesión. La sesión es generalmente para el almacenamiento a corto plazo. Para cualquier dato transaccional, nunca debe mantenerlo en sesión, sino almacenarlo en tablas relacionales directamente.

Siempre estoy a favor de no usar Session. Los desarrolladores abusan de la sesión todo el tiempo. Cada vez que quieren pasar datos de una página a otra, simplemente lo colocan en la Sesión. Resulta en un mal diseño. Si realmente desea escalar a 100K base de usuarios concurrentes, diseñe su aplicación para no usar ninguna sesión en absoluto. Todos los datos transaccionales deben almacenarse en la base de datos. Cart es un objeto transaccional y, por lo tanto, no es adecuado para mantener la sesión. En algún momento, necesitaría saber cuántos carros se inician pero nunca se colocan. Por lo tanto, deberá almacenarlos en la base de datos permanentemente.

Recuerde, la sesión basada en la base de datos no es más que una serialización basada en datos. Piensa cuidadosamente en lo que estás serializando en la base de datos. Deberá limpiarlo también, ya que Session_End no se activará para la sesión basada en la base de datos o, de hecho, para la mayoría de las sesiones fuera de proc. Entonces, esencialmente le estás dando a los desarrolladores la capacidad de simplemente serializar datos en la base de datos y eludir el modelo relacional. Siempre resulta en una mala codificación.

Con almacenamiento relacional permanente, liderado por un caché de alto rendimiento como memcached, tiene un diseño mucho mejor para admitir una gran base de usuarios.

Espero que esto ayude a sus preocupaciones.

+0

Gracias por la respuesta, muy interesante. De hecho, apuntamos a 5000 clientes para nuestra plataforma durante los próximos 2 años, cada cliente tiene alrededor de 300 usuarios. Para cada cliente, proporcionamos una plataforma de registro, los períodos de registro generalmente son al mismo tiempo para todos nuestros clientes (=> peeks).Como los artículos vendidos se agotaron en menos de 5 minutos, es difícil estimar la cantidad de "usuarios concurrentes". Al leerlo, tal vez sobreestimé nuestro objetivo. Dirigirse a 20K usuarios concurrentes parece más razonable. Para las sesiones, parece malo almacenar la sesión con Memcached. – dervlap

+2

respuesta muy detallada e informativa! – ljubomir

Cuestiones relacionadas