30 votos

Java hilo por cada modelo de conexión vs NIO

Es el no-bloqueo de Java NIO aún más lento que el hilo de rosca estándar por conexión asincrónica socket?

Además, si usted fuera a utilizar los hilos por la conexión, le acaba de crear nuevos hilos o tendría que utilizar un gran hilo de la piscina?

Estoy escribiendo un MMORPG servidor en Java que debe ser capaz de escala de 10000 clientes fácilmente dado lo suficientemente potente hardware, aunque la cantidad máxima de los clientes es de 24000 (que creo que es imposible de alcanzar para el hilo por el modelo de conexión debido a un 15000 hilo límite en Java). De tres años de edad artículo, he oído que el bloqueo de IO con un hilo por cada modelo de conexión era todavía un 25% más rápido que el NIO (es decir, este documento http://www.mailinator.com/tymaPaulMultithreaded.pdf), pero puede que el mismo todavía lograrse en este día? Java ha cambiado mucho desde entonces, y he oído que los resultados eran cuestionables cuando se comparan las situaciones de la vida real debido a que la VM no era de Java de Sun. También, porque es un MMORPG servidor con muchos usuarios concurrentes que interactúan el uno con el otro, el uso de la sincronización y el hilo de prácticas de seguridad para disminuir el rendimiento hasta el punto donde un solo subproceso NIO selector de servir a 10000 clientes será más rápido? (todo el trabajo no tiene por que ser procesados en el hilo con el selector, puede ser procesado en subprocesos como la forma de MINA/Netty obras).

Gracias!

13voto

irreputable Puntos 25577

NIO de los beneficios debe ser tomado con un grano de sal.

En un servidor HTTP, la mayoría de las conexiones son las conexiones keep-alive, que se inactiva la mayoría de las veces. Sería un desperdicio de recursos para pre-asignar un hilo para cada uno.

Para MMORPG, las cosas son muy diferentes. Supongo que las conexiones están constantemente ocupados recibiendo instrucciones de los usuarios y el envío de más reciente del estado del sistema a los usuarios. Un hilo que se necesita más tiempo para una conexión.

Si el uso de NIO, se tendrá que constantemente re-asignar un hilo para una conexión. Puede ser un inferior de la solución, a la simple fijo-hilo-por-solución de conexión.

El valor predeterminado de hilo tamaño de la pila es bastante grande, (1/4 MB?) es la razón principal por la que no sólo puede ser limitado por los hilos. Trate de reducir y ver si el sistema puede soportar más.

Sin embargo, si su juego es de hecho muy "ocupado", es la CPU que usted tiene que preocuparse más. NIO o no, es muy difícil de manejar miles de hyper los jugadores activos en una máquina.

9voto

Jay Puntos 2003

En realidad, hay 3 soluciones:

  1. Varios subprocesos
  2. Un subproceso y NIO
  3. Ambas soluciones 1 y 2 en la misma tiempo

La mejor cosa a hacer para que el rendimiento es tener un pequeño número limitado de hilos y multiplex eventos de la red en estos hilos con NIO como los nuevos mensajes que llegan a través de la red.


El uso de NIO con un hilo es una mala idea por varias razones:

  • Si usted tiene múltiples procesadores o núcleos, que será ralentí recursos, ya que sólo se puede utilizar un núcleo en un momento, si solo tienes un hilo.
  • Si usted tiene que bloquear por alguna razón (tal vez para hacer un acceso a disco), la CPU está inactiva cuando podría ser el manejo de la otra conexión, mientras que usted está esperando el disco.

Un hilo por cada conexión es mala idea, ya que no escala. Digamos que tiene:

  • 10 000 conexiones
  • 2 CPUs con 2 núcleos cada uno de los
  • a sólo 100 hilos será bloquear en cualquier momento dado

Entonces usted puede trabajar fuera de que sólo se necesita 104 hilos. Más y se está desperdiciando recursos en la gestión de subprocesos adicionales que usted no necesita. Hay un montón de contabilidad bajo el capó necesaria para administrar de 10 000 hilos. Esto ralentizará.


Esta es la razón por la que se combinan las dos soluciones. También, asegúrese de que su VM es el uso de la forma más rápida de llamadas al sistema. Cada sistema operativo tiene su propio y único sistema de llamadas de alto rendimiento de e / s de red. Asegúrese de que su VM es el uso de la última y más grande. Creo que este es epoll() en Linux.

Además, si usted fuera a utilizar los hilos por la conexión, le acaba de crear nuevos hilos o tendría que utilizar un muy grande el hilo de la piscina?

Depende de cuánto tiempo usted desea pasar la optimización. La solución más rápida es crear recursos como hilos y cuerdas cuando sea necesario. Luego vamos a la recolección de basura reclamación cuando hayas terminado con ellos. Usted puede conseguir un aumento de rendimiento por tener un pool de recursos. En lugar de crear un nuevo objeto, que pedir a la piscina para uno, y volver a la piscina cuando hayas terminado. Esto se suma a la complejidad de control de concurrencia. Este puede ser optimizado aún más con el avance de la concurrencia de los algoritmos como el de no-bloqueo de algoritmos. Las nuevas versiones de la API de Java tiene un par de estos. Usted puede pasar el resto de su vida haciendo estas optimizaciones en un solo programa. ¿Cuál es la mejor solución para su aplicación específica es probablemente una cuestión que merece su propio post.

7voto

Peter Lawrey Puntos 229686

Si estás dispuesto a gastar cualquier cantidad de dinero en lo suficientemente potente hardware ¿por qué limitarse a un servidor. google no utiliza un servidor, que incluso no utilizar un centro de datos de los servidores.

Un concepto erróneo común es que NIO permite a los no-bloqueo IO de ello es el único modelo de la pena de benchmarking. Si usted referencia el bloqueo de NIO usted puede obtener un 30% más rápido que los antiguos IO. es decir, si se utiliza el mismo modelo de subprocesamiento y comparar los modelos de OI.

Para un juego sofisticado, usted es mucho más probable que se ejecute fuera de la CPU antes de llegar a 10K conexiones. De nuevo es más fácil tener una solución que las escalas horizontal. Entonces usted no necesita preocuparse acerca de cómo muchas de las conexiones que usted puede conseguir.

¿Cuántos usuarios pueden razonablemente interactuar? 24? en el que caso de que usted tiene 1000 grupos independientes que interactúan. Usted no tendrá este muchos núcleos en un único servidor.

Cuánto dinero por los usuarios son que usted tiene la intención de pasar en el servidor(s)? Usted puede comprar un 12 servidor principal con 64 GB de memoria de menos de £5000. Si el lugar de 2500 usuarios en este servidor ha pasado de 2 € por usuario.

EDIT: tengo una referencia http://vanillajava.blogspot.com/2010/07/java-nio-is-faster-than-java-io-for.html que es el mío. ;) Yo tenía esta revisado por alguien que es un GURÚ de Java de Redes y de manera general de acuerdo con lo que había encontrado.

1voto

Kevin Jin Puntos 433

Como la mayoría de ustedes están diciendo que el servidor está obligado a ser encerrado en el uso de la CPU antes de 10k usuarios simultáneos que se han alcanzado, supongo que es mejor para mí hacer uso de una rosca de bloqueo (N)IO enfoque teniendo en cuenta el hecho de que para este particular MMORPG, recibiendo varios paquetes por segundo para cada jugador no es infrecuente y puede saturar un selector si uno fuera a ser utilizado.

Peter levantó un interesante punto de que el bloqueo de NIO es más rápido que las bibliotecas antiguas, mientras que irreputable mencionó que para un largo MMORPG servidor, sería mejor usar los hilos, por la cantidad de instrucciones que se reciben por jugador. No cuento con demasiados jugadores que van inactivo en este juego, así que no debería ser un problema para mí tener un montón de no-ejecución de subprocesos. Me he dado cuenta de que la sincronización es todavía necesario, incluso cuando se utiliza un marco de referencia basado en NIO, ya que utilizan varios subprocesos que se ejecutan al mismo tiempo para procesar los paquetes recibidos de los clientes. El cambio de contexto puede llegar a ser caro, pero te voy a dar esta solución de un intento. Es relativamente fácil para refactorizar el código para que yo pudiera usar un NIO marco si me parece que hay un cuello de botella.

Creo que mi pregunta ha sido contestada. Voy a esperar un poco más para recibir más información a más gente. Gracias por todas tus respuestas!

EDIT: finalmente he elegido mi curso de acción. De hecho, estuve indeciso y decidió utilizar JBoss Netty y permitir al usuario cambiar entre cualquiera de oio o nio con las clases

org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
org.jboss.netty.channel.socket.oio.OioServerSocketChannelFactory;

Bastante agradable que Netty soporta tanto!

1voto

Usted puede conseguir un poco de inspiración de la ex Sol patrocinio del proyecto, que ahora se llama: http://www.reddwarfserver.org/

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X