Encuesta

¿Tienes intención de emplear a Java FX?

01-01-2009 - 122 votos

(1)

¿Están lloviendo de nuevo Cometas e Hilos?

27/11/2008 00:05 jmarranz

He publicado un nuevo artículo en CometDaily.com. El artículo inicialmente revisa la técnica usada en ItsNat para proporcionar Comet en la forma long-polling. Dicha técnica está basada en el estándar servlet un hilo por petición. A lo largo del artículo se revisa la falsa creencia de que los sistemas basados en múltiples hilos (IO) son lentos y no escalables respecto a las técnicas modernas de muy pocos hilos basándose en NIO.

En los últimos años se ha estado apostado por la técnica de comunicaciones asíncronas (no bloqueantes), por ejemplo en servidores de aplicaciones, en contra de la técnica basada en hilos o síncrona (hilo por conexión, en donde los hilos se bloquean cuando no pueden leer o escribir).

Como justificación se partía de la idea de que la técnica de comunicación asíncrona es superior tanto en rendimiento y en escalabilidad a la técnica clásica síncrona. Dicha idea se basó inicialmente en el proyecto SEDA basado a su vez en la tesis doctoral de Matt Welsh en torno a 2001. En el ámbito Java se ha concretado en el predominio del uso de NIO en vez de IO (el proyecto SEDA está también basado en Java).

El artículo plantea que la tesis de Welsh era válida en aquella época sobre todo en sistemas Linux basados en el kernel 2.4 o anteriores y máquinas virtuales Java antiguas.

A pesar del paso del tiempo, que ha conllevado una drástica mejora en la gestión de hilos que introdujo el kernel 2.6 (Linux NTPL), la disminución del "coste" de la sincronización de hilos en las máquinas virtuales modernas y la normalización de los sistemas multi-núcleo (lo que hace nada práctico el modelo SEDA puro de un sólo hilo), la idea de que la técnica NIO es superior en rendimiento y escalabilidad a IO, ha seguido prevaleciendo aunque sin datos modernos que lo justificaran.

El artículo cuestiona esta creencia a partir de las investigaciones de Paul Tyma, ingeniero software en Google, en donde a través de varios tests da la vuelta a las asunciones típicas de este terreno tal y como que NIO tiene mayor rendimiento que IO para una sola conexión o que en la gestión de muchas conexiones concurrentes la solución IO o basada en muchos hilos (hilo por conexión) no es escalable porque la gestión de muchos hilos tiene un alto coste de tiempo (cuantas más conexiones, más hilos, más degradación). Paul concluye por tanto que IO no sólo es más rápido que NIO en una sola conexión, además la escalabilidad no se ve prácticamente en nada afectada por el aumento de hilos (los tests de Tyma abarcan hasta 1000 conexiones-hilos).


El estudio de Paul Tyma finalmente plantea que a fin de cuentas la gestión de conexiones y gestión de datos (estado o contexto) de dichas conexiones en NIO es básicamente lo mismo que ocurre en el kernel del sistema operativo en la gestión de hilos, pues en realidad los procesadores (más exactamente cores) son en general monohilo, y por tanto la conmutación de hilos es básicamente un problema de software similar al de la conmutación entre conexiones, en ambos casos para hacernos creer que existe un verdadero paralelismo.

Finalmente el artículo concluye que el estudio de Paul Tyma al haberse realizado en el nivel de conexión (sockets), no puede extrapolarse directamente a un nivel de servlet al existir más capas y un protocolo concreto (HTTP). Lo que ciertamente determinan los tests de Tyma es que ya no puede afirmarse con rotundidad la superioridad incuestionable de NIO frente a IO, diferentes escenarios pueden dar ligeras ventajas a uno u otro pero difícilmente una técnica será ampliamente superior
en rendimiento y escalabilidad a la otra pues en cierto modo ambas técnicas son esencialmente similares e IO tiene la ventaja de su mayor facilidad de programación.

 

Volver a actualidad

Etiquetas: j2ee, comet, cometdaily, itsnat, ajax, web, thread, nio, seda

Comentarios: 27

  • logongas 26/11/2008 23:54

    Hola jmarranz,
    la comunicación asincrona en principio es más escalable que la sincrona simplemente porque el cliente no espera inmediatez. Entonces se ponen las peticiones en una cola de mensajes y no se procesan hasta que no haya recursos sufientes para atenderla por lo que el servidor no se suele saturar. Si es sincrona al estar el cliente esperando la respuesta inmediatamente se suele atender nada más llegar para responder lo antes posible haciendo que el servidor se sature si hay demasiadas peticiones simultaneas.
    Aunque de forma sincrona se puede retrasar el proceso de la petición, la conexión para la respuesta si que la mantienes ocupada y los datos no se guardan para su posterior proceso como se suele hacer en una cola de mensajes.

  • vieiro 27/11/2008 01:43

    @jmarranz, ¡Buen artículo!. De lo mejorcito que he visto por aquí últimamente. Enhorabuena. Supongo que todo esto es una consecuencia del aumento de capacidad de multiprocesamiento en los procesadores.

    @logongas, "...que el servidor se sature si hay demasiadas peticiones simultáneas..." los servidores (empresariales) no se saturan, o multiplexan la CPU (reduciendo el número de hilos, como hace NIO) o multiplexan los recursos (reduciendo el número de descriptores de fichero, como hace IO). Lo que viene a decir jmarranz es que no hay una diferencia apreciable en las dos, y que hoy por hoy IO es mejor.

     

     

     

  • Anónimo 27/11/2008 08:55

    Gran articulo sí, hace tiempo que no leia algo así por javahispano.

  • eferrandez 27/11/2008 09:12

    A medida que aumenta la capacidad de los recursos físicos (procesadores, ancho de banda, etc) la tendencia del software debe buscar ocultar la complejidad más que mejorar el rendimiento (siempre con excepciones, claro). Aunque el enfoque bloqueante fuese inferior en rendimiento y escalabilidad frente al no bloqueante yo optaría por el primero en función del principio de que una máquina es más barata que una persona. Si además ya no puede afirmarse con rotundidad la superioridad incuestionable de NIO frente a IO, la elección es clara.

    Excelente artículo jmarranz.

  • greeneyed 27/11/2008 09:20

    Habia leido el thread original así que no me ha sorprendido tanto, pero no quita que sea un buen resumen. En cuanto a lo que comentas, logongas, la cuestion es que la diferencia entre IO,NIO no es lo que la gente se imagina de que con IO dejes la conexión abierta esperando mientras el usuario "se toma un café" y decide hacer otra petición, es más a nivel de red, donde usas un solo canal por que los paquetes de red del mismo mensaje no te llegan todos seguidos y entonces se pueden aprovechar las "pausas" entre paquetes para servir atender paquetes de otros mensajes... es decir, más micro-management de sockets que lo que parece a primera vista.

    Lo que hay en juego es la gestión de Threads vs la micro-gestion de las comunicaciones. Y básicamente lo que se viene a decires que con lo que han mejorado los S.O. y las máquinas virtuales, ya no es tan ineficiente la gestión a alto nivel (Threads) y en algunos casos puede dar mejor rendimiento y ser más mantenible (el código para hacer micro-management de las comunicaciones es ordenes de magnitud más complejo).

    Me parece recordar que leí en otro artículo que el siguiente paso "natural" era que los desarrolladores de S.O. se pusieran a mejorar la gestión de las comuniocacione, y entonces quizá vuelva a haber mayor diferencia entre una estrategia y otra.

    De todas formas, lo que si estoy totalmente de acuerdo es que no hay que extrapolar directamente esas experiencias al nivel de servlets y conexiones HTTP, comet etc. y habria que estudiarlo. En este caso, intuititivamente parece que dadas las latencias, el tiempo de espera... etc.  el caso se parecería más a lo que plantea logongas y la comunicación asincrona siga ofreciendo ventajas sustanciales. Pero bueno, habria que comprobarlo para no quedarse sólo en "parece que..."

    Enhorabuena por el artículo ;)

  • jmarranz 27/11/2008 09:56

    logongas no te entiendo muy bien pero en los dos casos IO y NIO se trata de responder lo más rápido posible en cuanto hay posibilidad de leer (hay datos pendientes) o de escribir (el canal ha quedado libre), el que se pueda "bufferear/encolar" datos por ejemplo antes de escribir no es exclusivo de ninguna técnica, y como dice greeneyed el hilo está bloqueado porque no tiene nada que hacer pero otros hilos están ahí dale que te pego. En el caso de NIO el selector es también bloqueante cuando no hay nada que hacer lo que ocurre detrás del selector es que otro hilo está preguntado constantemente a todas las conexiones ¿alguna novedad?, que es más o menos lo que ocurre realmente con un hilo bloqueado, el "verdadero hilo gestor de hilos" está preguntando todo el rato si hay alguna novedad (alguien quiere que el hilo siga) para entonces despertar el hilo.

    Ciertamente si un servidor de aplicaciones tiene abiertos muy pocos hilos pues obviamente se saturará, es como si en NIO a propósito dejaran de registrarse en el selector conexiones a partir de un cierto número y no se procesaran (estarían bloqueadas).

    Lo que podríamos deducir a partir del estudio de Tyma es que a lo mejor muchos problemas de saturación de servidores de aplicaciones clásicos se deben simplemente a que el número máximo de hilos permitidos es raquítico porque nos hemos dejado llevar por la falsa creencia de que gestionar muchos hilos machacan el servidor de aplicaciones. Las curvas de Tyma dicen todo lo contrario por lo menos hasta 1000 hilos (que es lo que él ha estudiado), el impacto es prácticamente cero, es decir la diferencia de coste de la gestión de 2 a 1000 hilos es prácticamente nulo.

    Indudablemente los hilos ocupan memoria, de eso no hay duda, pero el coste de creación de un hilo también se ha reducido drásticamente por ejemplo en el kernel 2.6 de Linux, a lo mejor tenemos que volver a la práctica de la creación de hilos bajo demanda más que a mantener un pool fijo.

    El "mérito" del artículo es de Paul Tyma en cierto modo yo soy un re-empaquetador del conocimiento. Me interesó mucho el tema porque tiene un enorme impacto en Comet con long-polling y yo creo que nadie había relacionado el estudio Tyma con la técnica long-polling.

    Para aplicaciones web "normales" este tema no es relevante pues el uso de NIO o IO es un asunto interno del servidor de aplicaciones que solo interesa a los programadores de los mismos, el estándar servlet impone por ahora 1 request 1 hilo lo cual no impide que la técnica de comunicación por abajo sea NIO y como las requests terminan "pronto" y se liberan sus hilos el servidor no está obligado a usar un número indeterminado de hilos sino el número más apropiado.

    En el ámbito Comet (long-polling) este asunto tiene una enorme importancia pues en ese ámbito inevitablemente hay que "sujetar" el request, con la técnica IO se sujeta también el hilo lo que supone que el servidor ha de permitir muchos hilos si se quiere soportar muchos usuarios Comet.

    La suposición de no escalabilidad de IO por culpa de la gestión de muchos hilos hacía suponer que el aumento inevitable del número de hilos daba lugar a una degradación progresiva del rendimiento (no sólo por el obvio aumento de usuarios simultáneos). Por ello los servidores de aplicaciones (contenedores de servlets) se han lanzado a crear nuevas APIs "servlet" que se saltan el estándar permitiendo requests asíncronas, es decir en donde se pueda sujetar el request sin bloquear el hilo.

    El problema de estas técnicas es que aparte de la no estandarización la programación es más complicada pues es a base de eventos cuando lo normal en comunicaciones es programar de forma secuencial siguiendo el flujo de datos que queremos leer/escribir (en el caso de servlets sólo escribir).

    El estudio de Tyma viene a decir que se había dado por muerto a IO cuando está más vivo que nunca, de todas formas Tyma no habla en general de servidores de aplicaciones web o de servlets.
     
    Para los que no conozcais NIO y eso de los selectors aquí hay un estupendo tutorial:

     http://www.cs.brown.edu/courses/cs161/papers/j-nio-ltr.pdf

    La sección 9 es la que interesa en este caso.

     

  • logongas 27/11/2008 10:46

    Hola a todos,
    no no estaba defendiendo concretamente a NIO vs IO sino que aludía a la frase de jmarranz de:
    Como justificación se partía de la idea de que la técnica de comunicación asíncrona es superior tanto en rendimiento y en escalabilidad a la técnica clásica síncrona
    Desde mi punto de vista esa afirmación sigue siendo válida por lo que ya he explicado y por aclarar un poco me refería a sistemas tipo JMS con comunicaciones asincronas y colas de mensajes.
    Lo que no tiene mucho sentido es que si la comunicación es asincrona estemos constantemente pidiendo al servidor si el resultado ya está. Ya que si se hizo asincrono significa que no vas a tener inmediatamente el resultado y que puede retrasarse "bastante".

    Saludos

  • vieiro 27/11/2008 11:07

    Es importante mencionar que aunque un hilo de Java se quede "bloqueado" eso no implica una pérdida de rendimiento del procesador. Los hilos de Java se mapean a uno (o más) hillos del sistema operativo, por lo que si un hilo Java se queda "bloqueado" la CPU puede aprovechar y "currar" en otro hilo Java. 1000 hilos Java se pueden hacer funcionar con 20 o 30 hilos de sistema operativo.

    La máquina virtual Java se encarga de hacer eso de forma automática (con la ayuda de un buen sistema de hilos en el sistema operativo, no como aquellos "green threads" de juguete que había en las máquinas virtuales de hace unos años).

    Lo que yo entiendo del artículo es que no hay diferencia apreciable entre tener varios canales "esperando actividad" y tener varios hilos Java "esperando actividad". Tanto los canales como los hilos consumen recursos, y con las mejoras de las máquinas virtuales modernas, tener hilos "esperando" no es problemático ya.

    Un buen artículo para "ahuyentar viejos fantasmas", que siempre es de agradecer...

     

     

  • jmarranz 27/11/2008 11:23

    logongas creo que ya te endiendo, yo creo que estás confundiendo el tema, el que necesites enviar un mensaje y no necesites respuesta ni siquiera garantía de que ha llegado tiene poco que ver (no digo que nada que ver) con que se utilice NIO o IO.

    Tú dejas el mensaje a enviar en la cola y ya sea el hilo NIO o un nuevo hilo IO (u obtenido de un pool) ya se encargará de enviarlo, el debate tiene más que ver con que si es más efectivo enviar dicho mensaje usando un hilo(s) NIO o un hilo IO, que como ves no tiene mucho que ver con la necesidad de enviar un mensaje asíncronamente, pues si te das cuenta dejas el mensaje *completo* y encargas que "alguien" (claramente otro hilo) lo envíe. Como ves tu llamada JMS no tiene por qué decidir la técnica de comunicación empleada, lo único que decide es que *otro* hilo ha de hacerlo.

     

  • jmarranz 27/11/2008 11:35

    viero: con las mejoras de las máquinas virtuales modernas, tener hilos "esperando" no es problemático ya

    Yo creo que ese mérito se lo lleva fundamentalmente el kernel, lo que sí ha conseguido Java es que la "uncontended synchronization" tenga un coste prácticamente nulo y eso muy importante y es cosa de Java.

    La "uncontended synchronization" es cuando llamas un método o entras en un bloque synchronized en donde no hay ningún lock (no hay otro hilo dentro), esa comprobación de si hay un lock era bastante costosa en las primeras máquinas virtuales, ahora es prácticamente nulo dicho coste.

    Otro logro es evitar en IO lo más posible la sincronización de hilos y se tiende a usar cuando se puede las utilidades de concurrencia (java.util.concurrent) evitando así "parar" el hilo cuando hay otro hilo al mismo tiempo accediendo a un dato compartido.

    Incluso en este asunto synchronized vs concurrent en donde parece que claramente se dice que es mejor (si se puede) usar las utilidades de concurrencia en vez de synchronized en su momento leí a alguien que también niega dicha afirmación (supuestamente con pruebas) pero es un tema que por ahora me pilla lejos porque estoy inevitablemente anclado en la API de la JVM 1.4 (snif).

     

     

  • vieiro 27/11/2008 11:51

    Sí, claro, hay una combinación de factores. Las mejoras de la JVM a nivel de sincronización, las mejoras a nivel de kernel en threading (a pesar de todo Solaris sigue teniendo un thread scheduling superior a Linux) y las mejoras de las CPU a nivel de multicore.

    Si es que hoy por hoy nuestros sistemas están desaprovechados: mi QuadCore se "aburre" esperando a que le lleguen más threads.

    Y no quiero ni pensar en los Niagara de Sun. Con uno de esos me río yo de Java NIO.

    La verdad es que sí, están lloviendo hilos, (estaba visto) y vaya tormenta que se nos avecina...

     

  • jmarranz 27/11/2008 11:51

    vieiro: Tanto los canales como los hilos consumen recursos

    Yo creo que más que los canales (los cuales también existen en IO) es el contexto de la conexión, el gestionar en que fase está, cuantos datos han sido enviados/recibidos, cuantos quedan, información sobre lo que hay que hacer en la siguiente fase etc. Son cosas que en IO están en la pila y en el propio código de las llamadas y que en NIO hay que gestionar de forma explícita y normalmente a través de eventos.

    Afortunadamente todo esto nos pilla muuuy lejos a nivel de programación si no nos salimos de la programación web y para las cosas habituales tal y como leer de un archivo usamos IO que es más sencillo, al parecer NIO es más rápido con archivos grandes (en pequeños es al revés) pero el código es más complicado (no tengo la fuente a mano).

    El problema es que hacemos long-polling "a pelo" estas cosas hay que plantearselas porque si se sigue una via NIO hay que usar las APIs especiales de los servidores de aplicaciones, aunque hay una API, Atmosphere, del padre de Grizzly (el componentes de comunicaciones de GlassFish), que simplifica bastante este asunto.

    IceFaces e ItsNat por ejemplo ocultan todo esto al usuario porque son APIs de alto nivel.  

     

     

     

  • jmarranz 27/11/2008 12:02

    viero: Con uno de esos me río yo de Java NIO.

    Para ser justos hay que decir cualquier motor de comunicaciones NIO es hoy inevitablemente multihilo precisamente para poder usar los verdaderos hilos concurrentes que maneja un núcleo (que en los Intel Core yo creo que es sólo uno de verdad que me desmienta alguien si lo sabe) y en general para aprovechar los sistemas multinúcleo y multiprocesador. Incluso en mono-núcleo-mono-hilo-de-verdad es inevitable usar más de un hilo en NIO porque es casi imposible que un hilo no se bloquee "algo" al interaccionar con el hardware y deje aburrido al procesador durante algunos instantes. Por tanto la gestión, sincronización, conmutación entre hilos es también inevitable en NIO. Ciertamente NIO usa "los justos" de acuerdo con el hardware, no está obligado a adaptarse al número de conexiones (el caso de IO).

     

     

  • logongas 27/11/2008 12:13

    Hola jmarranz,
    como ya he dicho no estaba hablando del tema NIO vs IO sino de comunicaciones sincronas vs asincronas ya que en la noticia se habla algo de eso. Y lo decía porque JMS y los EJB de mensajes son los grandes temas olvidados en los desarrollos. Y pienso que esto es así simplemente porque es más dificil hacer sistemas asincronos que sincronos y eso nos lleva a olvidar las ventanas que tienen los sistemas asincronos.
    Por ejemplo ¿cuanta gente sabe que existe o se ha leido el libro Enterprise Integration Patterns? Un libro fundamental sobre el tema.

    Saludos.

  • greeneyed 27/11/2008 13:42

    como ya he dicho no estaba hablando del tema NIO vs IO sino de comunicaciones sincronas vs asincronas ya que en la noticia se habla algo de eso.

    El problema de eso es que es sacar fuera de contexto lo que se dice en el artículo para un contexto concreto. En el contexto de IO/NIO, se tenía la creencia de que las comunicaciones asíncronas eran inherentemente superiores y se ha demostrado que ya no es cierto. De otros contextos no dice nada el artículo, o más bien sí pero para decir que las conclusiones no son trasladables, así que no es "justo" usar las conclusiones del artículo en otro contexto, donde no son aplicables, y decir que no son ciertas por que en ese otro contexto no son ciertas.

    Pero si, las comunicaciones asincronas son las grandes olvidadas, cuando se pueden hacer cosas bastante interesantes. Nosotros combinando motores de tareas programadas y JMS hemos podido hacer algunas cosas interesantes que de forma sincrona hubieran sobrecargado el servidor en un solo Thread.

  • Marioko 27/11/2008 14:34

    excelente articulo, apenas lo he leido de pasada (mas tarde lo leo con calma), este tema de IO vs NIO es el que mas me ha llamado la atencion en este año. Y articulos como este hacen que uno piense un poco mas abierto en todos los temas.

    Con respecto a esta parte que mencionas:

    "There is significant evidence, people, and products focused on the goodness of asynchronous servlet containers or using techniques avoiding threads in general: IceFaces offers a custom asynchronous servlet container, while GlassFish, Tomcat and Jetty are pushing solutions of containers with the promise of very few threads servicing many clients" 

     ICEfaces en realidad utiliza un mecanismo propio para peticiones asincronas cuando detecta que el server donde se esta ejecutando no lo soporta directamente. En Jetty y Glassfish por ejemplo, es capaz de autoconfigurarse y utilizar las Continuations o Grizzly dependiendo del caso y se activa en modo ARP. En otros servers como Tomcat, toca configurarlo manualmente, tanto el server como la aplicacion. 

     Por eso mencione una vez que hasta el momento para mi ICEfaces es que el mas abstrae todo este tema IO vs NIO y te permite cometear una aplicacion sin practicamente ningun problema y esfuerzo.

    Por otra parte, es cierto que actualmente el hardware y las JVM estan mucho mas optimizadas para soportar cientos y hasta miles de usuarios sin que el desarrollador se preocupe tanto por los detalles.

    Saludos y de nuevo excelente articulo! 

     

  • jmarranz 27/11/2008 14:38

    greeneyed no es para tanto, ciertamente todas mis afirmaciones estan en el contexto NIO vs IO.

    Lolongas tiene razón "esperar pa na" es tontería. Por cierto lo del RPC asíncrono lleva ya inventado un porrón de años y estandarizado por ejemplo en el viejo CORBA.

    Lo de que las comunicaciones asíncronas son las grandes olvidadas no estoy de acuerdo, más bien lo contrario, pero es un tema para otro debate.

    Otra cosa.

    Como no quiero que se acabe entendiendo el artículo como un anti-NIO, para los creyentes en las bondades de NIO hay esperanzas para ellos.

     Esta es una comparativa de Jean-Francois Arcand (el de Grizzly) en donde enfrenta GlassFish con su motor NIO con Tomcat 5.5.16 basado en IO en torno al 2006:

    "¿Puede un Grizzly correr más rápido que un Coyote?"

    http://weblogs.java.net/blog/jfarcand/archive/2006/03/can_a_grizzly_r.html

    Y sí, más o menos gana GlassFish a Tomcat, pero antes de que se empiecen a abrir las botellas de champán, cava o vino barato (que estamos en crisis), hay que precisar unas cuantas cosas:

    1) Está hecho por Jean-Francois Arcand el padre de una de las partes, aunque no dudo de su buena fe a lo mejor el ajuste de Tomcat lo podría haber realizado alguien de Tomcat (aunque ciertamente Jean-Francois estuvo también implicado en el desarrollo de Tomcat).

    2) El test prueba peras con manzanas, es decir confronta dos servidores de aplicaciones diferentes en donde hay muchas más cosas que IO y NIO. Es decir concluir que la técnica NIO es superior a IO en este test es llegar muy lejos. 

    3) La victoria es muy muy poco significativa en la mayoría de los tests, en alguno GlassFish pierde y sólo en uno gana muy claramente.

    4) En la única prueba en donde gana claramente se dice "Real world benchmark, the purpose of my second benchmark is to stress the server with a real world application that contains complex Servlet, JSP and Database transaction". Es decir demasiadas cosas metidas como para extrapolar a IO/NIO

    5) La versión de GlassFish está basada en el propio Tomcat: "GlassFish Catalina is based on Tomcat 5.0.x (plus severals performance improvement)", es decir es un "Tomcat mejorado".

    6) El test se hizo hace más de dos años, las cosas han cambiado, Tomcat 6 y GlassFish v3 están por ahí fuera.

    El propio Jean-Francoises consciente de que no hay mucha ventaja por medio usa la frase siguiente para introducir el artículo: "Or can an NIO based HTTP connector be as fast as a traditional IO HTTP Connector...?"

    Por último no hay que dejarse llevar por frases como "Yes, you read it it correctly. Tomcat needs 500 threads where Grizzly needs only 10. NIO non-blocking is facinating, is it?" porque da la impresión de que con menos se hace más, lo que no cuenta Jean-Francoises es que Grizzly internamente ha de gestionar el estado de las 300 conexiones de test, cambiando continuamente entre ellas para simular el paralelismo que de fábrica se consigue usando hilos.

    Conclusión ¿Grizzly es más rápido y escalable que Coyote? seguramente, pero en aquel momento por  muy poco y por tanto la introducción de NIO no parece que haya servido para conseguir que sea "mucho mejor", es más, parece confirmar la conclusión de Paul Tyma, que al final se está haciendo lo mismo (simular el paralelismo en las comunicaciones) de dos formas "en esencia" iguales.

     

     

  • Marioko 27/11/2008 14:48

    si no estoy mal, la verdadera gracia de NIO es cuando existen miles (n x 1000) usuarios trabajando concurrentemente. Si mal no recuerdo, en unas pruebas que hicieron con Jetty, este podria soportar "hasta 11000" usuarios concurrentes... voy a ver si encuentro los resultados y los coloco aqui..

  • jmarranz 27/11/2008 15:37

    El problema Marioko es que los tests que puedes encontrar recientemente comparando Jetty, Tomcat y GlassFish utilizan las últimas versiones, pues los tres ya tienen NIO en sus entrañas.

    Si volvemos al mundo de los hilos, crear hilos es barato:

    http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library

    "In tests, NPTL succeeded in starting 100,000 threads on a IA-32 in two seconds"

    ¡¡100.000!! Vale ¿pero cuanto tiempo se tardará en procesar el trabajo que tenga que hacer cualquiera de esos 100.000 hilos en paralelo?

    En el ejemplo que tú citas el "hasta" sugiere que en torno a los 11000 el Jetty estará totalmente ahogado y a partir de ese valor empezará a rechazar conexiones, el problema es que esos 11000 usuarios concurrentes ya pueden ir a tomar café porque aunque hayan sido aceptados, a poca cosa que haga cada usuario hará que al sumar 11000 veces lo mismo de para un buen rato. No nos engañemos cualquier procesador como se decía antes tiene muy muy poquitos hilos verdaderos, concretamente los Intel Core uno por núcleo y basta, los Pentium 4 decían que dos pero vamos en realidad como mucho 1 y medio y yo creo que me paso.

    Por Internet puedes encontrar noticias como que Tomcat 6 soporta hasta 16000 conexiones, muchas más que GlassFish y Jetty. Aparte de alguna réplica desde el mundo GlassFish, como comenta Greg Willkins de Jetty ¿para qué aceptar tantas conexiones si no las vas a poder procesar?. Las comparativas del máximo número de conexiones concurrentes apenas sirven para ver quien la tiene más grande (la escalabilidad) pero en aplicaciones reales ¿cuanto tiempo tendrán que esperar esos 16000 usuarios a que terminen las 16000 operaciones sobre la base de datos y manipulaciones correspondientes?.

    A partir de un cierto número de tareas "falsamente" concurrentes (ya sea via NIO o con threads en IO) el sistema deja responder con la prontitud razonable de forma INEVITABLE. Lo importante del estudio de la escalabilidad no es conocer el máximo (absurdo) posible, sino estudiar si el incremento de usuarios concurrentes NO INFLUYE en el tiempo de proceso medio empleado por cada usuario, o mejor dicho, el mejor índice de escalabilidad es el del número de usuarios (conexiones) concurrentes a partir del cual el tiempo medio de proceso dedicado a cada usuario empieza a aumentar significativamente.

    En su estudio Paul Tyma afirma que por lo menos hasta 1000 hilos en IO el tiempo dedicado a cada conexión no varía practicamente nada, que al sistema le da igual 2 hilos que 1000 (al usuario no claro, pero eso pasa en IO en NIO y en PIO-PIO).

     

  • Marioko 27/11/2008 15:57

    no habia pensando en eso, pero tienes razon, el maximo numero de conexion no significan necesariamente todo ese numero de usuarios enCRUDeciendo la aplicacion. :-)   lo que citas sobre NPTL , joder 2 segundos?? ufff 

     

    "En su estudio Paul Tyma afirma que por lo menos hasta 1000 hilos en IO el tiempo dedicado a", asum entonces que esos 1000 hilos podrias atender a mas de mil usuarios, cierto? Es algo asi como los pools de conexiones de base de datos segun tengo entendido.

    mmm has hablado sobre linux, y su kernel. Actualmente tengo desplegada una aplicacion sobre un server windows con Jetty y SQL Server 2005, tengo pensado instalar ubuntu server para Jetty y en otro colocar la BD. Teniendo en cuenta lo que se ha comentando, el Jetty deberia funcionar mucho mejor ejecutandose sobre linux que en windows, ¿estoy en lo cierto? o la diferencia no es mucha....

    saludos

  • jmarranz 27/11/2008 16:19

    Marioko: asum entonces que esos 1000 hilos podrias atender a mas de mil usuarios, cierto?

    No, no es eso.

    A ver si me explico:

    Supongamos que estamos en monoprocesador con un único "hilo hardware", supón que un hilo IO recibe 1Mb de datos, supongamos que está él solito (imposible, cualquier sistema tiene más hilos por ahí pero bueno) y tarda 1 segundo en leer ese Mb.  Dos hilos leyendo cada uno 1Mb con dos conexiones diferentes sin nada compartido, idealmente se necesitarán 2 segundos, ambos hilos tardarán 2 segundos, pues realmente el hilo hardware es el que hace el trabajo y lo reparte equitativamente y ambos hilos terminan al mismo tiempo (tras 2 seguntos), por tanto el tiempo empleado en el procesador por cada hilo (usuario, conexión etc) sigue siendo 1, es decir 2 segundos/2 hilos = 1 seg/hilo.

    Supongamos que hay 1000 hilos haciendo lo mismo y que todo es bonito e ideal, el tiempo empleado total será 1000 segundos por tanto sigue siendo el tiempo dedicado a cada hilo 1000 seg/1000 hilos = 1 seg/hilo. Ahora supongamos que a partir de 1000 se tuerce la cosa y que por ejemplo para 2000 hilos el tiempo empleado es 6000 seg, por tanto 6000 seg/ 2000 hilos = 3 seg / hilo, es decir cuantos más hilos más tiempo se dedica a cada hilo para hacer lo mismo, esos 2 segundos de exceso podemos atribuirlos a la propia gestión de los hilos, la propia gestión emplea tiempo de procesador que no es tiempo de trabajo real (leer datos), el sistema se degrada. Es como cuando haces varias cosas a la vez a ratitos al final el tiempo de adaptación al cambiar de tarea te lleva más tiempo que la propia tarea.

    Evidentemente 1000 segundos de espera puede ser totalmente inaceptable para el usuario pero eso no significa que el sistema vaya mal, es sistema puede estar respondiendo estupendamente bien desde el punto de vista de la escalabilidad, sencillamente no puede hacerlo más pronto de ninguna manera posible. Pero cuando tarda 6000 segundos no sólo la espera es mucho mayor, es que el sistema está fatal y cada nuevo usuario lo lleva peor.

    Este análisis también es aplicable a NIO substituyendo hilo por conexión.

    Tyma no dice nada de qué pasa a partir de 1000 hilos, seguramente a partir de 1000 hilos la cosa se empieza a poner chunga, pues claro que puede admitir muchos más de 1000 hilos si con 1000 hilos el coste de gestión ha sido prácticamente cero.

     

  • jmarranz 27/11/2008 16:23

    Respecto a lo de Linux y Windows, yo no soy el más adecuado para responder, no hay que olvidar que Windows tiene también versiones server, en las versiones desktop la gestión del UI tiene gran prioridad lo cual no necesariamente ocurre en el server.

    Lo que sí dice Paul Tyma es que Windows XP no lo hace nada mal en la gestión de hilos y da el dato que incluso en Windows XP, IO supera a NIO en el caso de una sola conexión.

     

  • Marioko 27/11/2008 16:26

    Ahhhhhh caramba ahora si la cache!!

    try{

        //entender explicacion

    }catch(Explicacion ex){

        //catcheada

    }

    ;-)

    Muchas gracias por tomarte el tiempo y explicar esto detalladamente!!

    Salu2

  • atesti 27/11/2008 17:09

    Hablando de falsas creencias, existe otra falsa creencia que dice que el desarrollo de agentes asicrónicos es mucho más dificil que el de agentes síncronos. Eso es falso, ya que la dificultad es inherente al lenguaje con el que se desarolla más que a la metodología que se utiliza. Con esto quiero decir, que para el caso exclusivo de Java, la gestión de concurrencia asincrónica es muy dificultosa por la carencia de closures. Pero en el caso de lenguajes funcionales esto es muy diferente, y ejemplo de ello son Scala y fundamentalmente Erlang, que demuestran que la abstracción de Actores es muy sencilla de implementar, y no distingue threads de procesos, ni locales de remotos.

  • atesti 27/11/2008 17:12

    Tampoco se puede pretender transparencia cuando existen regiones criticas y una red entre medio. La transparencia absoluta en ese caso es una falacia.

  • logongas 28/11/2008 05:39

    @atesti:"la gestión de concurrencia asincrónica es muy dificultosa por la carencia de closures"

    ¿Quieres decir que con closures es más facil hacer una función de CallBack porque puedes acceder desde ella a todas las variables de la función que realizó la llamada asincrona?

  • Anónimo 02/12/2008 14:07

    En la siguiente (la q esta saliendo ahora) iteracion de la arquitectura de intel vuelve hyperthreading (o los casi-hilos). Alguien sabe si los hilos de Niagara son muy distintos a los de Intel? (2 hilos por core, 2-4-8 cores por procesador). Y luego esta Larrabee (esto aun no se comercializa) que son 8-16-32-64 ... pentium pros en un chip para desde GPU hasta como copro multinucleo ...

Escribe tu comentario

Sun Microsystem Logo NHT-Norwick Logo

© 2002-2007 Asociación javaHispano