asp.net scalability viewstate

asp.net - ¿Moviendo ViewState fuera de la página?



scalability (15)

Estamos tratando de aligerar la carga de nuestra página tanto como sea posible. Como ViewState a veces puede llegar a 100k de la página, me encantaría eliminarlo por completo.

Me encantaría escuchar algunas técnicas que otras personas han usado para mover ViewState a un proveedor personalizado.

Dicho eso, algunas advertencias:

  • Servimos un promedio de 2 millones de visitantes únicos por hora.
  • Debido a esto, las lecturas de la base de datos han sido un problema grave en el rendimiento, por lo que no quiero almacenar ViewState en la base de datos.
  • También estamos detrás de un equilibrador de carga, por lo que cualquier solución tiene que funcionar con el usuario que rebota de máquina a máquina por devolución de datos.

Ideas?


¿Cómo manejas Session State? Existe un proveedor integrado "store the viewstate in the state". Si está almacenando el estado de la sesión en algún sistema fuera de proc rápido, esa podría ser la mejor opción para viewstate.

editar: para hacer esto, agregue el siguiente código a las clases de su página / clase base de la página global

protected override PageStatePersister PageStatePersister { get { return new SessionPageStatePersister(this); } }

Además ... esto de ninguna manera es una solución perfecta (o incluso buena) para un gran estado visual. Como siempre, minimice el tamaño de viewstate tanto como sea posible. Sin embargo, SessionPageStatePersister es relativamente inteligente y evita almacenar un número ilimitado de viewstates por sesión, así como también evita almacenar solo un viewstate por sesión.


Debido a la hinchazón organizativa típica, la solicitud de nuevo hardware lleva mucho tiempo, y la solicitud de hardware que implicaría una reconexión completa de nuestra configuración actual probablemente reciba una gran resistencia por parte del departamento de ingeniería.

Realmente necesito encontrar una solución de software, porque ese es el único mundo sobre el que tengo control.

Yay for Enterprise :(


He intentado encontrar algunos de los productos que había investigado en el pasado que funcionan igual que StrangeLoops (pero basados ​​en software) Parece que se fueron todos a la quiebra , lo único de mi lista que todavía existe es ScaleOut pero están especializados en el almacenamiento en caché del estado de la sesión.

Entiendo lo difícil que es vender soluciones de hardware a la alta gerencia, pero siempre es una buena idea, al menos, lograr que la gerencia acepte escuchar al representante de ventas del hardware. Estoy prefiriendo poner algo de hardware que me presente una solución inmediata porque me permite (o me compra algo de tiempo) realizar otro trabajo real.

Entiendo, realmente apesta, pero la alternativa es cambiar el código para la optimización y eso podría costar mucho más que obtener un dispositivo.

Avíseme si encuentra otra solución basada en software.


He probado muchas formas de eliminar la carga del estado de visualización de la página y entre todos los hacks y algunos programas de software, lo único que realmente es escalable es el dispositivo StrangeLoops As10000 . Transparente, sin necesidad de cambiar la aplicación subyacente.


Voy a ver si puedo encontrar una forma de aprovechar nuestro servidor de estado actual para contener ViewState en la memoria, debería poder usar la ID de sesión del usuario para mantener las cosas sincronizadas entre las máquinas.

Si se me ocurre una buena solución, eliminaré cualquier código de protección IP y lo pondré para uso público.


¿Has considerado si realmente necesitas todo ese estado visual? Por ejemplo, si llena una cuadrícula de datos de una base de datos, todos los datos se guardarán en viewstate de manera predeterminada. Sin embargo, si la cuadrícula es solo para presentar datos, no necesita un formulario de all, y por lo tanto no viewstate.

Solo necesita viewstate cuando hay alguna interacción con el usuario a través de devoluciones, e incluso entonces los datos del formulario pueden ser suficientes para recrear la vista. Puede desactivar viewstate de forma selectiva para los controles en la página.

Tienes una IU muy especial si realmente necesitas 100K de viewstate. Si reduce ViewState a lo que es absolutamente necesario, podría ser más fácil y más escalable para mantener ViewState en la página.


El siguiente funciona bastante bien para mí:

string vsid; protected override object LoadPageStateFromPersistenceMedium() { Pair vs = base.LoadPageStateFromPersistenceMedium() as Pair; vsid = vs.First as string; object result = Session[vsid]; Session.Remove(vsid); return result; } protected override void SavePageStateToPersistenceMedium(object state) { if (vsid == null) { vsid = Guid.NewGuid().ToString(); } Session[vsid] = state; base.SavePageStateToPersistenceMedium(new Pair(vsid, null)); }


Almacene viewstate en un objeto de sesión y use un caché distribuido o un servicio de estado para almacenar la sesión separada de los servidores we, como microsofts velocity.


Sé que esto es un poco rancio, pero he estado trabajando durante un par de días en un "dispositivo virtual" de código abierto usando squid y ecap para:

1.) gzip 2.) manejar ssl 3.) reemplazar viewstate con un token a petición / respuesta 4.) Memcache para el almacenamiento en memoria caché de objetos

De todos modos, parece bastante prometedor. Básicamente, se sentaría frente a los loadbalancers y realmente debería ayudar al rendimiento del cliente. Tampoco parece ser muy difícil de configurar.


Publiqué un blog sobre esto hace un tiempo: la solución está en http://www.adverseconditionals.com/2008/06/storing-viewstate-in-memcached-ultimate.html

Esto le permite cambiar el proveedor de ViewState a uno de su elección sin tener que cambiar cada una de sus clases de página, mediante el uso de un PageAdapter personalizado. Almacena el ViewState en memcached. En retrospectiva, creo que es mejor almacenarlo en una base de datos o en un disco: llenamos los archivos de Memcached muy rápidamente. Es una solución de baja fricción.


Siempre puede comprimir ViewState para que pueda obtener los beneficios de ViewState sin tanta hinchazón:

public partial class _Default : System.Web.UI.Page { protected override object LoadPageStateFromPersistenceMedium() { string viewState = Request.Form["__VSTATE"]; byte[] bytes = Convert.FromBase64String(viewState); bytes = Compressor.Decompress(bytes); LosFormatter formatter = new LosFormatter(); return formatter.Deserialize(Convert.ToBase64String(bytes)); } protected override void SavePageStateToPersistenceMedium(object viewState) { LosFormatter formatter = new LosFormatter(); StringWriter writer = new StringWriter(); formatter.Serialize(writer, viewState); string viewStateString = writer.ToString(); byte[] bytes = Convert.FromBase64String(viewStateString); bytes = Compressor.Compress(bytes); ClientScript.RegisterHiddenField("__VSTATE", Convert.ToBase64String(bytes)); } // ... } using System.IO; using System.IO.Compression; public static class Compressor { public static byte[] Compress(byte[] data) { MemoryStream output = new MemoryStream(); GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true); gzip.Write(data, 0, data.Length); gzip.Close(); return output.ToArray(); } public static byte[] Decompress(byte[] data) { MemoryStream input = new MemoryStream(); input.Write(data, 0, data.Length); input.Position = 0; GZipStream gzip = new GZipStream(input, CompressionMode.Decompress, true); MemoryStream output = new MemoryStream(); byte[] buff = new byte[64]; int read = -1; read = gzip.Read(buff, 0, buff.Length); while(read > 0) { output.Write(buff, 0, read); read = gzip.Read(buff, 0, buff.Length); } gzip.Close(); return output.ToArray(); } }



Como dije anteriormente , he usado la base de datos para almacenar el ViewState en el pasado. Aunque esto nos funciona, no nos acercamos a los 2 millones de visitantes únicos por hora.

Creo que una solución de hardware es definitivamente el camino a seguir, ya sea que use los productos StrangeLoop u otro producto.


Es posible que tenga una solución simple para ti en otra publicación. Es una clase simple de incluir en su aplicación y algunas líneas de código en la página asp.net. Si lo combina con un sistema de almacenamiento en caché distribuido puede ahorrar una gran cantidad de pasta ya que ViewState es grande y costoso. La velocidad de Microsoft podría ser un buen producto para adjuntar este método también. Si lo usa y ahorra una tonelada de dinero, me encantaría mencionarlo un poco. Además, si no está seguro de algo, hágamelo saber y puedo hablar con usted en persona.

Aquí está el enlace a mi código. Texto del enlace

Si le preocupa escalar, entonces se considera que el uso del token de sesión como identificador único o el almacenamiento del estado en sesión funciona más o menos en un escenario de granja de servidores web.


Oh no, burocracia . Bueno, esto va a ser una tarea difícil de llenar. Usted mencionó aquí que usa un servidor de estado para atender su estado de sesión. ¿Cómo tienes esta configuración? ¿Quizás puedas hacer algo similar aquí también?

Editar

Awh @Jonathan, publicaste mientras escribía esta respuesta. Creo que ir por esa ruta podría ser prometedor. Una cosa es que definitivamente requerirá mucha memoria.

@ Mike . No creo que almacenarlo en la información de la sesión sea una buena idea, debido a la intensidad de la memoria de viewstate y también a la cantidad de veces que necesitará acceder al viewstate. Se accede a SessionState con mucha menos frecuencia que viewstate. Yo mantendría los dos separados.

Creo que la solución definitiva sería almacenar el ViewState en el cliente de alguna forma y tal vez valga la pena mirarlo. Con Google Gears , esto podría ser posible ahora.