Mostrando entradas con la etiqueta rendimiento. Mostrar todas las entradas
Mostrando entradas con la etiqueta rendimiento. Mostrar todas las entradas

martes, julio 12, 2011

Martin Fowler analiza la arquitectura de LMAX

martes, julio 12, 2011 por Martín

Allá por Enero, escribía sobre la arquitectura de LMAX, una empresa que había desarrollado una aplicación para operar en mercados de derivados pero no sólo orientada a traders sino también al usuario final, y que presentaba unos números impresionantes. En InfoQ publicaron un video muy interesante donde los creadores de la arquitectura la explicaban en detalle.

Un amigo me ha pasado hoy este enlace, donde el mismísimo Martin Fowler ha hecho un análisis mucho más detallado sobre la arquitectura, complementado por notas que ha intercambiado por email con los autores. Si os interesa el tema de la escalabilidad y la computación de alto rendimiento entonces es un artículo que no os debéis perder.

miércoles, julio 06, 2011

Todo lo que deberías saber sobre Linux y MySQL y nunca te atreviste a preguntar

miércoles, julio 06, 2011 por Martín

Yoshinori Matsunobu es Principal Infrastructure Architect en DeNA, habiendo sido previament MySQL Lead Consultant en MySQL/Oracle/Sun, aunque ahora he visto en su blog que es Oracle ACE Director. Hace unas semanas me topé con unas transparencias de un tutorial de 3 horas que dió en la MySQL Conference and Expo 2011, y que sin ninguna duda es la biblia de MySQL y Linux.

jueves, junio 16, 2011

HPCC Systems alternativa Open Source a Hadoop

jueves, junio 16, 2011 por Martín

Ayer apareció en todos los medios de comunicación, aunque yo me enteré por el grupo de escalabilidad en español (toma promo gratuita). Una compañía de Miami, LexisNexis ha anunciado que hará Open Source su tecnología de computación y análisis de datos HPCC Systems (High Performance Computing Cluster) a la que la prensa no ha dudado en tildar como el Hadoop Killer.

jueves, enero 27, 2011

Consejos para crear aplicaciones de alto rendimiento

jueves, enero 27, 2011 por Martín

Siguiendo con el post anterior, sobre la presentación sobre LMAX en InfoQ, de mi resumen me restaba comentar los seis consejos que ellos daban para la creación de aplicaciones de alto rendimiento que fuesen capaces de gestionar un gran número de transacciones con una latencia muy baja.

Su máxima era: hoy en día con un único hilo puedes jugar con 3 billones de instrucciones por segundo. Con no hacer nada estúpido tendrás 10 mil transacciones por segundo sin problemas. ¿Pero cómo hacemos para no meternos en problemas? Aquí resumo sus consejos:

martes, enero 25, 2011

Consejos para gestionar 100K TPS con menos de 1ms. de latencia

martes, enero 25, 2011 por Martín

Hace poco más de un mes publicaron en InfoQ una presentación muy interesante sobre como crear aplicaciones capaces de procesar un gran número de transacciones con una latencia muy pequeña.

Los autores de la presentación fueron Martin Thompson y Michael Barker y trabajan en LMAX. Esta copañía desarrolla lo que se llama un Trading Exchange. Este tipo de compañías ofrecen la posibilidad de comprar activos financieros al usuario final (i.e. nosotros) ofreciendo un pool de proveedores (agencias de trading, bancos, etc.) que compiten entre sí para ofrecerle al usuario el mejor precio. La idea es que si por ejemplo quiero comprar EUR/USD el sistema me va a ofrecer siempre la mejor oferta de entre los varios proveedores existentes en el trading exchange.

domingo, diciembre 26, 2010

Escribiendo micro-benchmarks con jmicrobench

domingo, diciembre 26, 2010 por Martín

Tal y como escribía hace unos días, mi opinión es que los microbenchmarks no son una técnica recomendada para sacar conclusiones sobre el rendimiento global de nuestros programas.

Sin embargo sí que existe una serie de circunstancias en las que es importante el conocer el rendimiento de tu lógica de negocio. Por ejemplo cuando estamos trabajando en sistemas que requieren procesar una gran cantidad de transacciones por segundo. Imaginaros quizás un sistema de pagos por Internet, o el software de una casa de apuestas, o la línea de almacén de un gran fabricante de lo que sea.

En estos casos no sólo es necesario el tener la confianza en que el software va a soportar el volumen esperado sino que es necesario garantizarlo. ¿Cómo lo podemos garantizar? Con tests. Pero hacer los tests puede ser complicado. Por eso se hacen útiles frameworks para la creación de microbenchmarks como jmicrobench del que nunca había oido hablar pero que en breve os contaré en otro post como he llegado a el.

jmicrobench es una extensión de jUnit que define un nuevo ejecutor de Tests: PerformanceTestRunner que se encarga de ejecutar nuestros tests y de calcular el número de operaciones por segundo que ejecuta, su media, e incluso de generar gráficas. Un test de rendimiento se crearía de la siguiente forma:

jueves, diciembre 23, 2010

GC: Only the good die young

jueves, diciembre 23, 2010 por Martín


Una frase popular dentro del frikimundo de la Garbage Collection es "Only the good die young", que proviene además de una canción bastante popular de Billy Joel y que le viene que ni pintada.

Un poco de background para la frase. Todo esto depende de la máquina virtual utilizada, pero tomando como referencia Hotspot que es una máquina virtual generacional, tenemos que la memoria se divide en dos generaciónes: Young generation y Tenured generation. Cada una de estas zonas a su vez está dividida en otras zonas, pero esto lo vamos a obviar por razones de simplicidad.

La Young Generation es mucho más pequeña que la Tenured Generation. Por lo tanto, la recolección de basura ahí es mucho más rápida. Pero aún más importante, la recolección de basura en la Young Generation se hace constantemente y no requiere parar los diferentes threads de la máquina virtual de Java, mientras que normalmente (recordad, esto es una visión meramente pedagógica y simplificada) la recolección de basura en la Tenured Generation exige parar todos los threads de la máquina virtual.

viernes, noviembre 12, 2010

Microbenchmarks, lenguajes dinámicos y la web

viernes, noviembre 12, 2010 por Martín



Hay una frase en inglés que es "lies, dammed lies and statistics" y viene a significar que tenemos mentiras, malditas mentiras, y las estadísticas, y que se utiliza cuando la gente utiliza datos numéricos y estadísticas para intentar sustentar argumentos que de por sí pueden resultar débiles.

Hace unas semanas alguien me preguntaba en qué lenguaje podía hacer un proyecto web. Yo le contesté que podría probar Groovy o Ruby. A lo que el me respondió que había pensado en Java porque había visto muchos estudios que mostraban que estos lenguajes eran demasiado lentos. Pues bien, ahí tenemos un ejemplo del uso de números para fines interesados, en este caso para mover la balanza hacia un lenguaje u otro.

Es cierto que los lenguajes dinámicos son más lentos que los estáticos, ya que gran parte del procesado de los programas se posterga a tiempo de ejecución. Pero la cuestión es, ¿es esto realmente tan relevante? Quizás hace años lo fuese, en las primeras betas de cada lenguaje, pero ahora mismo definitivamente no lo es. A los que vivimos hace ya muchos años toda la historia del "Java es más lento que C++" creo que nos suena todo esto de algo.

Pero intentaré plasmar un ejemplo en esta entrada que creo que explica el por qué es absolutamente irrelevante la diferencia de rendimiento en el mundo de Internet. Imaginémonos algo de lógica de negocio. Java ahora ya está considerado como rápido, así que ¿cuanto nos podría llevar? Pongamos 10 ms. para hacer fácil el ejemplo. Ahora imaginémonos el mismo código en Groovy cinco veces más lento, o sea que serían 10 milisegundos. La gráfica de rendimiento nos quedaría como sigue:

Una nota: si buscáis por Internet os encontraréis órdenes de magnitud de todo tipo, desde 3x hasta 300x, muchos de estos tests son incorrectos por el hecho de usar tipos de datos primitivos, y cualquiera que haya usado Groovy/Ruby/Python/etc. habréis visto que esos ordenes de magnitud tan grandes son irreales. Si os interesa aquí explican más.

Pero volviendo al ejemplo, partimos de 10 ms. contra 50 ms. que es de por sí una diferencia de rendimiento muy importante (y reitero que lejos de la realidad). ¿Escogeríais directamente Java?, a fin de cuentas parece mucho más rápido. Bueno, antes de contestar y ya que estamos hablando de aplicaciones web, introduzcamos en la gráfica el resto de componentes de una petición típica: DNS, servidores varios, bases de datos, etc. A ver como queda la cosa:



¡Vaya! La diferencia que antes parecía tan enorme ahora ya no lo parece tanto. Aclaro que he utilizado valores que a mi me han parecido adecuados. Seguro que serán diferentes si hacéis un estudio serio sobre el tema, pero creo que no irán desencaminados. Hagamos cuentas:

  • DNS: 60 milisegundos

  • Latencia: 200 milisegundos

  • Apaches, weblogics, tomcats, etc.: 160 milisegundos

  • Base de datos: 200 milisegundos


En resumen y sumando nuestra lógica de negocio del caso anterior:

  • Lógica de negocio en Java: 630 milisegundos

  • Lógica de negocio en Groovy: 670 milisegundos


Sorpresa, sorpresa. Lo que era un 5x ahora es un 1.06x O dicho de otro modo, si antes parecía que había un 500% más de rendimiento ahora se ha convertido en un 6%, y creo que he sido bastante generoso.

Y ¿a dónde quiero ir con todo este análisis? A que si estamos eligiendo un lenguaje para nuestro próximo proyecto, para nuestra plataforma corporativa, para nuestra startup, para ese proyecto de cliente, o para aprender, lo menos en lo que nos debemos fijar es en los microbenchmarks ya que no indican absolutamente nada. Hay excepciones. Claro que sí, siempre las hay. Por ejemplo si tenemos que programar algún algoritmo de cálculo intensivo que sólo hará eso, calcular, y donde no influyen factores externos; o programando autómatas; o creando aplicaciones en entornos muy limitados como móviles. En estos casos tenemos que tener más cuidado, pero no es lo habitual.

En la mayor parte de los casos lo más razonable es fijarse en otras características como lo fácil que será programar, el soporte de entornos de desarrollo, lo amplia que es la comunidad de ese lenguaje, la cantidad de documentación y libros disponibles, la cantidad de programadores que voy a poder encontrar en el mercado laboral, lo difícil que pueda ser la curva de aprendizaje, y muchas otras cosas que seguro que se os ocurren.

Pero el rendimiento.... ya no es tan fundamental como antes.

viernes, julio 03, 2009

Cuenta gratis en Pingdom

viernes, julio 03, 2009 por Martín


Nota muy rápida por si alguien no está subscrito al blog de Pingdom. Ayer anunciaron que desde ahora pasan a ofrecer gratuitamente su herramienta de monitorización de sitios web. No es una trial, es una cuenta totalmente gratis, incluyendo 20 alertas SMS. Eso sí, está limitada a un único sitio web o servidor.

Podéis coger vuestra cuenta aquí. Servicios parecidos son ExternalTest del que Enrique Domínguez me cedió amablemente invitaciones para los lectores de este blog o webpagetest.

Edit: Muy rápido. Después de haberme dado de alta, aclaro lo de las limitaciones porque es algo engañoso. El límite es por un único chequeo, y no por servidor o página web. Es decir, para un mismo sitio web no podrás crear varias alertas sino tan sólo una. Le resta un poco la utilidad pero bueno... es gratis.

lunes, diciembre 08, 2008

Cuenta gratuita en ExternalTest.com para los lectores de Pensamientos Agiles

lunes, diciembre 08, 2008 por Martín


Este es un post que me hace mucha ilusión ya que es absolutamente la primera vez en la que alguien se pone en contacto conmigo para regalar algo a través de este blog. Todo viene a raiz de este post y este comentario.

El autor del comentario es Enrique Dominguez y muy amablemente me ha ofrecido una cuenta grauita para su producto ExternalTest y, lo que es mejor, una cuenta grauita para todo lector de este blog al que le interese. Lo único que tenéis que hacer para reclamarla es registraros en ExternalTest y enviar un email al usuario Enrique en su dominio externaltest.com (supongo que entendéis esto, el que no lo entienda es que no merece la cuenta :P) simplemente mencionando en el subject "BRIGOMP".

Atención, es importante que enviéis el email con el mismo email que uséis para registraros. El tipo de cuenta es "gratuita ilimitada", por lo que no os caducará jamás y podéis configurar hasta tres tests diferentes. Si tenéis requisitos más complejos podéis contactar con Enrique.

ExternalTest es un producto muy interesante. La funcionalidad es la que se podría esperar en este tipo de productos, y sirve para monitorizar servicios, no sólo HTTP sino que muchos otros protocolos como FTP, POP3, DNS, etc. Además tiene un modo de análisis de rendimiento que te viene a ofrecer los mismos datos que explicaba en el post sobre webpagetest. Repitiéndome en lo comentado en dicho post, el mayor atractivo es la ejecución de tests desde diferentes localizaciones lo que nos permite evaluar el impacto de la latencia sobre nuestras páginas web.



ExternalTest es un servicio muy orientado al mundo empresarial pero cualquiera que tenga una página web le puede sacar partido. Yo mismo se lo he sacado hoy mismo cuando mi servidor se ha caido y he recibido el email de alerta. Hay otros servicios como Pingdom que vienen a hacer lo mismo pero por lo que me comenta Enrique, los servicios adicionales que ofrecen son bastante más limitados:

"Pingdom es un servicio similar en lo básico, nosotros tenemos productos más avanzados para empresas como XTbox o XTvirtuabox que permite a nuestros clientes contar con todas las capacidades de monitorización en entornos locales (esto lo usa por ejemplo Prisacom en España para probar las latencias existentes entre sus accesos locales y los realizados desde sudamérica, por ejemplo) o XTsec, que permite realizar de manera automatizada pruebas de vulnerabilidades conocidas sobre tu paltaforma..."


Muchas gracias Enrique por el detalle.

jueves, diciembre 04, 2008

Latencia, monitorización de redes y microbursts.

jueves, diciembre 04, 2008 por Martín


El software para operar en mercados de valores es realmente apasionante. Desde fuera puede parecer muy aburrido pero una vez que estás dentro descubres que se trata de una lucha constante por la optimización. Minimizar la latencia es fundamental. En ese mundo, el que consigue que sus operaciones lleguen antes al mercado es el ganador. Y ahí cualquier cosa, ya sean switches, routers, servidores de aplicaciones o esa clase Java que está al final de toda la cadena y que envía el mensaje a la cola de MQ son importantes.

Todas estas cosas se multiplican por 1000 cuando estamos en una época de incertidumbre, y que en cualquier momento el mercado puede bajar un 5% o una moneda puede desplomarse frente a otra en cuestión de minutos. Muchas empresas emplean herramientas de monitorización para tratar de descubrir patrones de operación en el mercado. Estas herramientas pueden ser internas, como Wily Introscope con la uqe he trabajado y que no puedo más que recomendar, o externas.

Las herramientas internas tienen la ventaja de integrarse muy bien con el stack de la aplicación y de ofrecer información bastante específica, como tiempos que tardan en procesarse mensajes en colas, o el tiempo que tarda en ejecutarse un método determinado, etc. Sin embargo el inconveniente es que añaden una carga extra de proceso que irremediablemente impacta en la latencia, por lo que al final te ves obligado a desplegar una versión con monitorización mínima en producción; aunque son fenomenales para desarrollo, ya que ahí puedes permitirte monitorizar muchos más datos.

Por otra parte hay herramientas externas que funcionan ajenas a las aplicaciones y servidores y que se basan simplemente en capturar el tráfico de las redes y en analizar sus patrones para proporcionar información, generar gráficos y lanzar eventos a partir de ésta. Dentro de este sector se encuentra Endace. Por cierto que si os interesa el tema, Corvil es una empresa irlandesa que está teniendo también bastante éxito en este mundillo.

En Low Latency han publicado un pequeño podcast/entrevista de siete minutillos que explica algunas de estas cosillas y que es bastante ameno de escuchar. Es un poco publicitario, porque el entrevistado es Paul Doyce, Technical Manager de Endace, pero se lleva bastante bien.

También os lo podéis descargar directamente desde este link.

Photo via travel_aficionado@Flickr.

miércoles, diciembre 03, 2008

Probando el rendimiento de páginas web con webpagetest

miércoles, diciembre 03, 2008 por Martín

El otro día por una lista de correo a la que estoy suscrito descubrí
webpagetest
(dos post seguidos de descubrimientos, esto ya parece el blog de "Martín el Descubridor"). Lo he estado probando y la verdad es que es una herramienta espectacular. Fundamental para el análisis de rendimiento de páginas web.

Por una parte, nos permite evaluar el impacto de la latencia en nuestra aplicación web, ya que podemos probar como se cargarían las páginas desde Estados Unidos y Nueva Zelanda. Una pena por cierto que no tengan ningún host en Europa.

Por otra parte, los informes que te muestra son realmente completos. Por defecto, webpagetest carga la página que le mandas dos veces. Una para evaluar la carga inicial, y dos para evaluar como funcionan las cachés. Lo que esperaríamos normalmente es que la segunda ejecución sea mucho más rápida que la primera. Veamos el resultado si cargamos por ejemplo la página de Twitter:



Ok, si hacéis clic en la imagen lo veréis mejor. Han sido 4.5 segundos. Algo lentillo diría yo, aunque cierto es que es un servidor con carga y que muestra bastantes cosillas en la página principal. Aún así, una de las cosas que me llama la atención es la cantidad de bloques naranjas que se ven. Los bloques naranjas son establecimiento de conexión, y no deberían suceder tan a menudo si tu servidor permite el establecimiento de conexiones persistentes, algo por otra parte bastante común en la mayoría de servidores. Patrick Meenan, el creador de webpagetest, lo explica muy bien en este post.



Esta segunda imagen nos da una mejor idea de como funciona twitter. Bastante caché, uso de ETags, librerías javascript comprimidas, imagenes comprimidas y no CDN. Interesante.



En la imagen superior se observa que la recarga de la página ha dado unos mejores resultados, aunque todavía se aprecia que se ha empleado un segundo entero en descargarse la librería de lightbox. Seguro que hay mucho que mejorar por ahí. Se sigue también apreciendo que el servidor no mantiene conexiones persistentes.

Y bueno, a parte de todo esto webpagetest te ofrece un informe en formato texto con todo lo que se debe arreglar.


Mmm, por cierto, que se me olvidaba una cosa. ¿Es importante la latencia? Probemos a cargar Twitter desde Nueva Zelanda:



7.2 segundos. 3 segundos más que desde los Estados Unidos. Pobres amigos de las antípodas que tienen que soportar estas cosas :)

Lo que no acabo de ver es por que aquí sí que se utilizan conexiones persistentes. O será que quizás el servidor no lo muestra... ¿álguien que me ayude con esto?

El servidor de Nueva Zelanda nos ofrece bastante detalle sobre las diferentes peticiones, y como veis todos los recursos están en Estados Unidos, así que se tendrá que notar el efecto del límite en la velocidad de la luz:



Bueno, no sé lo que os parece a vosotros pero a mi me parece una herramienta super útil.

sábado, marzo 08, 2008

Análisis de rendimiento y la necesidad de contratar especialistas

sábado, marzo 08, 2008 por Martín


Hace unos días, una persona de la que obviamente no voy a revelar ni el nombre ni nada sobre la empresa, me enviaba un correo en el que me preguntaba consejo:

Actualmente estamos en el proceso de implementacion de una aplicacion web en java, desarrollada utilizando JSF(ICefaces) + Spring + Hibernate, se esperan de 1000 a 2000 usuarios concurrentes, la aplicacion se accede desde todo el pais, de lado de la aplicaciones hemos echo bastante tunning, ej. No Lazy loading, No n+1 select, paginacion. Tambien al JVM un poco; pero apesar de eso, cuando llegamos a 500 usuarios activos la aplicacion ya no funciona.

JSF,Spring,Hibernate
Tomcat 6.14, Pool DBCP
Solaris 10 UltraSparcT1, 16 Micro Procesadores, 8 GB de RAM
JDK 1.5


El correo sigue con algunos detalles sobre pools:


<Resource name="jdbc/dsAcreditacion" auth="Container"
type="javax.sql.DataSource"
...
maxActive="25" maxIdle="10"

<Connector port="80"
maxThreads="500" minSpareThreads="25" maxSpareThreads="250"
maxHttpHeaderSize="8192" enableLookups="false"
redirectPort="8443" acceptCount="5000" connectionTimeout="20000"
disableUploadTimeout="true" maxKeepAliveRequests="1"/>


Y finalmente las dudas:

¿cuales cree que deberian ser las configuraciones para el pool de
conecciones y para el Connector de Tomcat, para manejar 1000 o 2000
usuarios recurrentes?

¿ hay alguna relacion entre cantidad de usuarios recurrentes y tamaño de
pool ?


Este, es el tipo de preguntas que muchas empresas obligatoriamente se plantearán llegado un determinado punto. Idealmente serían preguntas que el personal de sistemas sería capaz de responder ya que son los que tendrán que mirar por dichos servidores, aunque realmente el/los Arquitectos ya las deberían haber tenido en cuenta durante el diseño de la aplicación y deberían ser conscientes de las limitaciones de la arquitectura escogida y de su capacidad para escalar, y los desarrolladores deberían estar también minimamente familiarizados con algunos conceptos.

Pero, como no todo el mundo es de color de rosa, la realidad es que muchas empresas no tienen el personal adecuado para estas tareas. Ya sea por falta de experiencia, o por venir de otras plataformas, o por lo que sea, pero el caso es que muchas veces una empresa se encuentra sin respuesta para este tipo de preguntas.

En este caso, una opción es preguntar al autor de un blog. Sin embargo, yo sólo actuaré como médico de cabecera. No puedo solucionar el problema, simplemente podría decirte que estás malito, y que tu dolor en la barriga se puede deber a una intoxicación, o podría ser algo más grave, por lo que te recomendaría ir al especialista.

Siguiendo con el ejemplo anterior, puedo decir que la capacidad de no poder despachar más de 500 usuarios con esa configuración indica un problema. Podría ser que tengas un problema con las librerías que usas (AJAX?) y que el límite de 500 threads sea lo que te esté evitando el poder servir a más usuarios; o quizás decirte que el problema puede ser un memory leak que te evite escalar; o tal vez si la base de datos va a recibir muchas peticiones concurrentes, 25 hilos pueden hacer de cuello de botella; o que alojar un único tomcat en un máquina de 8Gb es tontería siendo sólo una de las razones que el tener un heap tan grande sería contraproducente y probablemente todo funcionase mejor con 4 tomcats con 2Gb cada, o quizás incluso más.

Y no es que no quiera o que me moleste especialmente que me preguntéis, pero es que todo esto no dejan de ser recomendaciones de alguien que en este caso actua como médico de cabecera. Alguien que por la distancia y por el desconocimiento tanto del negocio como de la aplicación y su arquitectura no puede dar más que una serie de sugerencias. Alguien que estando en la empresa durante unos días podría realmente ofrecer soluciones para esos problemas pero que moralmente no puede ofrecer un juicio de valor por la distancia.

En un caso como este, y a falta de ganas o presupuesto para contratar a personal con experiencia, lo ideal es contratar un especialista durante un tiempo. Alguien que se pase unas semanas con la aplicación y te redacte un informe de evaluación del rendimiento y de ofrezca sugerencias para su mejora. Alguien que te prepare un plan de monitorización de las aplicaciones. Alguien que se siente contigo y te asesore sobre los cambios necesarios en la arquitectura para mejorar su escalabilidad, resistencia, tolerencia a fallos, etc.

Estos especialistas no tienen porque ser necesariamente baratos. Pero como sugería en mi metáfora anterior, y como pasa en la vida real: "Una cosa es ir al médico de cabecera, o quedarse en casa automedicarse y otra muy diferente es ir al especialista".

Foto vía everyplace@flickr

miércoles, noviembre 28, 2007

Multi-tenancy: diseñando con la escalabilidad en mente

miércoles, noviembre 28, 2007 por Martín

Me ha gustado mucho un artículo que un compañero me ha pasado sobre el concepto de multi-tenancy. Se podría definir como la habilidad para ubicar varios clientes dentro de la infrastructura de una aplicación. Por otra parte, también me ha gustado una entrada de Jose Manuel Suarez en su blog en la que habla de optimización vs. hardware. Pensándolo esta tarde, me he dado cuenta de que, aunque no lo parezca a simple vista, existe bastante relación entre ambas entradas.

Como Fred Chong comenta en su blog, conseguir multi-tenancy es un trabajo duro. Por ejemplo, supongamos que tenemos una aplicación empresarial relativamente típica con un par de servidores web, un par de servidores de aplicaciones y un par de bases de datos, y que decidimos hacer nosotros el hosting de la aplicación. Realizar el hosting de la aplicación es mucho más práctico para la empresa proveedora de software ya que evita muchos problemas como el despliegue o la gestión de parches de cliente, al tiempo que hace más fácil la automatización; sin embargo, al mismo tiempo añade mucho coste en cuanto a infraestructura.

Por ejemplo el caso anterior está bien para un único cliente, ¿pero qué pasa cuando tenemos 5 clientes? En ese caso ya empezamos a hablar de 10 servidores web, 10 servidores de aplicaciones y 10 bases de datos a gestionar, y eso siempre que algún cliente no exija sistemas de demostración en cuyo caso las cifras pueden crecer todavía más. Excluyendo la administración, esto plantea dos problemas principales: el coste del hardware y el coste de las licencias de todo el software que estemos utilizando (servidores de aplicaciones, sistemas de monitorización, motores especiales como por ej. sistemas de comunicación para entornos financieros, sistemas de mensajería, etc.). ¿Qué pasa si estos 5 clientes son pequeños y no compensa el mantener esta infraestructura para ellos?

Esta es una de las razones por las que en aplicaciones complejas la aproximación "slashdot" o "youtube" de añadir servidores no funciona demasiado bien, ya que el escenario es más complejo.



El diagrama de aquí arriba muestra las diferentes técnicas que pueden aliviar el problema de multi-tenancy. Las técnicas están ordenadas por densidad, siendo las de más arriba las que permiten compartir más clientes dentro de nuestra infrastructura, y las de más abajo las que menos clientes permiten compartir.

No voy a entrar demasiado en detalle en las diferentes técnicas, porque eso es otra historia, pero básicamente cada una de esas técnicas tiene un coste asociado. Ya sea en cuanto a necesitar soluciones propietarias, o ser complejo de mantener, o ser funcionalidades específicas de un sistema operativo. Por ejemplo, la virtualización es una solución excelente para solucionar el problema de multi-tenancy pero tiene el problema de que el número de máquinas virtuales que podremos alojar en un servidor físico es limitado y a mayores tenemos el coste de las licencias (o del mantenimiento) del sistema de virtualización que utilicemos.

Y bueno, entonces, ¿cómo se puede arreglar todo este embrollo?

La solución ideal es crear aplicaciones que puedan utilizar varios clientes a la vez. Si la aplicación es muy grande, entonces se debería dividir en diferentes módulos independientes entre sí y que pudiesen ser compartidos por diferentes clientes. Por ejemplo, un sistema de trading financiero podría tener por una parte en un servidor la gestión de las carteras de los diferentes traders, en otro servidor la gestión de las órdenes de compra y venta de todos estos traders, y en otro servidor la gestión de informes para los clientes y los bancos.

Esto es lo que Fred Chong llama "Shared Application Instance", el compartir porciones de una aplicación con diferentes clientes. Esta es la aproximación que permite la mayor densidad de tenancy en un sistema, y la que ofrece la mejor escalabilidad. En estos sistemas, denominados comúnmente no-homogéneos, es mucho más sencillo gestionar los recursos del sistema. Por ejemplo, si sabemos que la gestión de órdenes necesita más recursos que la generación de informes, podemos dedicar servidores más potentes a alojar el cluster del sistema de órdenes mientras que reservaremos servidores más modestos para el reporting.

El problema, y ahora es cuando vuelvo a enlazar con el post de Jose Manuel, es que migrar una aplicación existente para que pueda dividirse y servir a diferentes clientes es algo muy complejo y muy costoso si la aplicación no se ha diseñado desde un principio para ello. En muchos casos estaríamos ante un reto casi tan complejo como el tener que reimplementar la aplicación. Ahí está la importancia de diseñar y crear una arquitectura desde un principio pensando en la escalabilidad. La optimización prematura siempre es algo malo, pero no lo es sin embargo el diseño en busca de la escalabilidad y el rendimiento. El diseño en busca de escalabilidad puede que no de frutos en los primeros meses, puede que añada complejidad lógica en el sistema (por ejemplo con desacoplamiento de APIs y módulos, uso de sistemas de mensajería, etc.), pero a largo plazo, cuando el sistema crece, y cuando hay más clientes a los que servir, es cuando se ven realmente los beneficios.

Vaya ladrillo que me ha quedado. Felicidades si has sido capaz de llegar hasta aquí :-)

miércoles, noviembre 14, 2007

Patrones de acceso y las 10 mejores maneras de estropear la escalabilidad y fiabilidad de Java

miércoles, noviembre 14, 2007 por Martín

Ayer estuve viendo el video que han publicado en Parleys de Cameron Purdy en la JavaOne 2007: "Top 10 Ways to Botch Enterprise Java Applications", y lo cierto es que es una charla muy recomendable. En la línea de la presentación que ya hiciera en la JavaOne del 2006 "Top ten ways to create a real J2EE disaster" y de la que ya hablara en mi abandonado blog en inglés (lagrimilla, sí, ... pero que verguenza de inglés).

Aquí hay un buen resumen de la charla así que me puedo ahorrar casi todos los comentarios. El caso es que el patrón número 10 me ha recordado mucho lo que hacemos, ya que es exactamente uno de los problemas que tenemos, y es de eso de lo que quería hablar. Se trata de la importancia de tener en cuenta los patrones de trabajo de una aplicación, es decir, que si uno simplemente asume que todos los datos son iguales y los trata por igual se puede llevar una sorpresa.

Como comenta en la transparencia 11, el negocio de Foreign Exchange se basa en la compra y venta de divisas. Sin embargo, la realidad es que la mayor parte de las operaciones se realizan sobre euros y dólares ya que es donde hay más volumen comercial. ¿Cómo afecta esto? Os pongo un ejemplo.Un sistema de Foreign Exchange normalmente tendrá un montón de órdenes en el sistema puestas por los traders para comprar y vender, ganar posiciones o retirarse. Esas órdenes se procesan en tiempo real con cada latido del sistema con lo que se genera tal enorme carga de CPU que se ha de distribuir la evaluación entre diferentes nodos de un cluster.

Ahora bien, si alguien que no conoce el negocio se pone a diseñar el sistema puede decidir que la evaluación de cada par de divisas se haga en un nodo del cluster. La consecuencia es que el 40% de la CPU la consumirá una única máquina que será la que evalue el par EUR/USD, mientras que a lo mejor otras 20 máquinas están consumiendo el otro 60% del volumen del mercado evaluando órdenes para divisas que no son tan utilizadas.

No me enrollo más. La charla son 50 minutillos y la verdad es que vale la pena.

sábado, noviembre 03, 2007

Una razón algo más técnica para no escribir métodos largos

sábado, noviembre 03, 2007 por Martín

Hoy en día creo que más o menos todo el mundo tiene claro que escribir métodos muy largos es una mala práctica. Nos lo dicen en la universidad, nos lo dicen en los libros de programación, de ingeniería del software, de patrones o de refactorización. Los paquetes de métricas y de detección estática de errores nos avisan de que nuestros métodos son demasiado largos y el jefe nos echará una buena bronca si ve que hacemos un método de 5.000 líneas.

Aún así, cuando uno está programando siempre hay esos momentos en que se siente un poco vago con algún método al que va añadiendo cosas y cosas, porque total, estamos haciendo sólo un boceto, ¿no? El problema es que esos bocetos se convierten en la versión definitiva (doy fe, que tengo un par de métodos grandes por ahí que verguenza me dan) y ahí ha quedado. Pero bueno, funciona, ¿no?. Y no lo va a tocar nadie nunca jamás de los jamases, ¿no?, ¿qué hay de malo entonces?. Pues sí, incluso creyéndonos que nadie verá ese código nunca, hay algo que puede ser malo:

Hoy en día los lenguajes populares se ejecutan en máquinas virtuales. Estas máquinas virtuales disponen de optimizadores que traducen el bytecode de nuestros programas en código máquina, pero que además realizan numerosas optimizaciones sobre el mismo para obtener mucho más rendimiento. Estas optimizaciones no sólo se limitan a reordenaciones, inlining y todas estas cosas sino que en algunos lenguajes como Java (no sé si en otros, supongo que sí) se almacenan mapas de objetos en los que se especifican donde se encuentran los objetos a los que apuntan las referencias: la referencia A está en un registro, la referencia B está en la pila, etc.

Dicha información se utiliza durante la recolección de basura para acelerar la ejecución. Si no se dipone de esos mapas de objetos en el momento de la recolección, el recolector los tendrá que crear por si mismo. Para crear estos mapas, el recolector trata de simular la ejecución del método en relación a la posición de la referencia que se pretende recolectar. A métodos más grandes, simulaciones más complejas. Por cierto, que además la simulación depende de en que línea salte la GC así que aunque los mapas se guardan, ésto no sirve de mucho si el método es grande.

¿Y qué tiene que ver esto con el tamaño de los métodos? Pues resulta que Java tiene un límite para el tamaño de los métodos a los que el JIT aplicará optimizaciones. Si los métodos sobrepasan ese límite no pasarán por el JIT, y por lo tanto estos mapas de objetos no se generarán, y por lo tanto la recolección de basura será mucho más larga de lo que debería ser. Más concretamente el límite son 8000 bytes de bytecode. Para deshabilitar este límite en la máquina virtual de Sun, se puede usar la opción "-XX:-DontCompileHugeMethods". Pero ojo, esto no es una buena idea ya que lo más probable es que el JIT también sufra a la hora de optimizar, a fin de cuentas si el límite lo han puesto así será por algo. Así que mejor refactorizar y hacer más métodos y más pequeños.

Bueno, ahora igual he engañado a alguno que estará pensando. ¡Qué listo es Martín, cuanto sabe! Pues no. Todo esto no me lo he encontrado, ni lo he vivido, ni nada de nada. No es más que un resumen, bueno más bien una traducción porque me ha quedado bastante largo, de lo que cuenta el genial Jon Masamitsu en su blog, en el que ha publicado una entrada en la que explica algunas experiencias que le han pasado con clientes, relacionadas con parámetros raros de la máquina virtual. Entre estas experiencias está la de un cliente que veía que los tiempos de GC eran enormes y que no sabía por que, pero que de pronto descubren que comentando el código los tiempos de GC son mucho menores.

Pues ya sabéis, ahroa si alguna vez habláis con alguien sobre esto de los métodos largos, y os dice que eso de la refactorización no son más que chorradas, os podéis sacar de la manga esta explicación que es de las de dejar con la boca abierta.

miércoles, octubre 10, 2007

Alto rendimiento en Wall Street

miércoles, octubre 10, 2007 por Martín

Bueno, aunque no he avisado algunos os habréis dado cuenta de la inusual inactividad de este blog. Se debe a que durante esta semana pasada he estado de mini-vacaciones, que han venido muy bien para cargar las pilas.

Una de las cosas que estuve haciendo antes de salir de vacaciones fue revisar unas presentaciones del evento High Performance on Wall Street. Las presentaciones las podéis descargar desde este enlace. Están en formato PDF, pero algunas se pueden escuchar que es lo realmente interesante.

En ellas se habla de las últimas tendencias en cuanto a rendimiento en Wall Street, que probablemente sea uno de esos lugares que marquen tendencias en para el futuro al menos en cuanto a temas de rendimiento, procesado de cantidades masivas de datos y latencia.

Escuchando las presentaciones se sacan varias conclusiones. Una es que ahora mismo no hay capacidad eléctrica para computar la cantidad de datos disponibles. No se trata ya de un problema de poder de computación de las CPUs si no más bien de cantidad de datos procesables por watio de energía. Comentan en alguna de las charlas que hoy por hoy es imposible procesar más datos sin dejar sin luz a todo Nueva York.

Al hilo del punto anterior, uno de los ponentes, que casualmente está muy familiarizado con el mundo Java, Cameron Purdy, apostaba por la orientación de las aplicaciones en Wall Street hacia los datos en lugar de hacia la CPU como una solución al problema del consumo de energía, al menos mientras que los green datacenters no estén todavía más extendidos. Este tipo de centros de datos en los que se apuesta por el bajo consumo fue otro de los temas de moda en la conferencia.

La virtualización y la computación en grid se plantean también como apuestas claras de futuro. Hay un par de ponencias disponibles sobre estos temas que resultan también interesantes.

Espero que os resulten interesantes.

martes, septiembre 04, 2007

High performance web sites: 13 reglas para conseguir páginas web más rápidas (video)

martes, septiembre 04, 2007 por Martín

El máximo responsable de rendimiento de Yahoo, Steve Souders realizó hace un mes una presentación sobre sitios web de alto rendimiento en la OSCON 2007. El caso es que, Steve, también autor del libro High Performance Web Sites, repitió la presentación en Yahoo hace unos días, y éstos la han puesto en la web para nuestro disfrute.



En la presentación habla sobre 13 reglas que han definido en el grupo de rendimiento de Yahoo para la creación de sitios web eficientes dentro de la compañía, explica cada una de las normas, y las diferencias entre seguirlas y no seguirlas, y por último habla un poco sobre YSlow.

Por cierto, las trece normas en orden de prioridad son:

1. Minimizar las peticiones HTTP
2. Utilizar una CDN
3. Añadir el tag expires a la cabecera HTML
4. Comprimir los diferentes recursos
5. Poner las CSS al principio de la página
6. Mover los scripts al final
7. Evitar las expresiones CSS
8. Externalizar los ficheros JavaScript y las CSS (y cachearlos)
9. Reducir las búsquedas DNS
10. Compactar el código JavaScript
11. Evitar la redirección
12. Eliminar scripts duplicados
13. Configurar los ETags

¿Alguna que se os ocurra?

martes, mayo 29, 2007

Java en tiempo real

martes, mayo 29, 2007 por Martín

Java Real-Time System 2.0 fue presentado por Sun Microsystems en la pasada JavaOne. Durante la última semana han aparecido unos cuantos enlaces sobre este sistema donde se explica a qué escenarios y sectores está orientado.
  • The case for Real-Time in the Enterprise : Entrevista a Greg Bollella y Dave Hofert, distinguished engineer y manager de Sun Real-Time Java Marketing respectivamente, en la Java One.
  • Real-Time Garbage Collection : Una nueva entrevista a Bollella y Hofert, sobre como funciona la recolección de basura en estos sistemas.
  • El podcast de Javaposse donde la segunda parte está también dedicada a Java Real-Time System 2.0 y donde también participan Bollella y Hofert.

Los tres enlaces anteriores son podcasts.

Por otra parte BEA Systems no se queda atrás y anuncia WebLogic Event Server una versión ligera de su servidor de aplicaciones, y WebLogic Real Time 2.0, que aseguran ofrece pausas de tan sólo 10 milisegundos.

En este artículo de BEA es donde se pueden leer las notas más interesantes. Como que según ellos, Java RTS pone realmente en apuros a las aplicaciones nativas escritas en C/C++ en cuanto a escalabilidad y rendimiento, o como uno de sus clientes dentro de los servicios financieros perdía 200.000 dólares al día hasta que comenzó a utilizar WebLogic RTS. Según promocionan en WebLogic, WebLogic Event Server es capaz de soportar la evaluación de 10.000 reglas y la ejecución de 50.000 transacciones complejas por segundo (no hay datos sobre el hardware utilizado para el test).

martes, mayo 22, 2007

Buen artículo sobre NIO 2

martes, mayo 22, 2007 por Martín

En artima han publicado una entrevista muy buena. a Alan Bateman, líder del JSR-203 (JSR 203: More New I/O APIs for the JavaTM Platform ("NIO.2")).

En el artículo se explican claramente las diferencias entre NIO y el futuro NIO 2 que aparecerá en Java 7. Entre las principales mejoras:
  • Nueva implementación de java.io.File con más rendimiento y funcionalidades.
  • Interfaz para monitorizar cambios en el sistema de ficheros (ej. editores).
  • Posibilidad de crear interfaces para sistemas de ficheros propios (ej. en memoria, en base de datos, en S3, ...).
  • Soporte de multicast para sockets
  • Nuevo modelo de entrada y salida basada en eventos para ficheros y sockets en lugar de polling

La parte final del artículo/entrevista está realmente bien ya que explica las ventajas de la entrada y salida basada en eventos en frente al actual sistema asíncrono. Básicamente la clave es:

The Selector in the current API can deliver great performance and scalability when mapped to an operating system that has a highly scalable polling interface—both Solaris and Linux have such interfaces for example. Asynchronous I/O delivers great performance when the underlying operating system has a high performance and scalable asynchronous I/O facility. The application and server design is also critical.

De todos modos, aún habrá que esperar bastante.