2010-09-03 12 views
19

Tornado anuncia como "una, no bloqueante infraestructura de servidor web relativamente simple" y fue diseñado para resolver el problema C10K. Sin embargo, mirando a su envoltura de base de datos, que se envuelve MySQLdb, me encontré con el siguiente fragmento de código:¿Tornado realmente no bloquea?

def _execute(self, cursor, query, parameters): 
    try: 
     return cursor.execute(query, parameters) 
    except OperationalError: 
     logging.error("Error connecting to MySQL on %s", self.host) 
     self.close() 
     raise 

Por lo que yo sé llamadas a la MySQLdb, que se construye en la parte superior de libmysqlclient, están bloqueando.

¿Estoy en lo cierto al pensar que una consulta de larga duración haría que todo el servidor de Tornado no responda hasta que termine o hay magia en el código?

+2

¿Qué esperas? No bloquear no significa que "todas las líneas se ejecutan simultáneamente". – zneak

+6

-1 por aceptar una respuesta incorrecta; un servidor web no bloqueador no debe bloquear las solicitudes debido al acceso a la base de datos (acceso al disco) para otras solicitudes. –

+1

Agradezco el comentario, pero creo que acepté la respuesta que responde a mi pregunta: el uso del contenedor de MySQL hará que todo el servidor se bloquee. La respuesta parece ser: sí, lo hará. Tornado no proporciona un grupo de procesos para hablar con MySQL, por lo que bloquea. Tu respuesta también tiene sentido, pero Nicholas estuvo aquí primero. – ipartola

Respuesta

16

Sí, ausentes otras medidas, el servidor esperará para la consulta para finalizar la ejecución. Eso no significa que Tornado no sea un servidor web no bloqueante.

Un "servidor web no bloqueo" no bloquea en la red de E/S (y puede tener alguna disposición para disco I/O si lo hace servir archivos estáticos). Eso no significa que obtenga una ejecución de instrucción instantánea que viole la causalidad en su aplicación.

Hacer una llamada de base de datos lleva tiempo, al igual que la lectura de archivos, formateo de cadenas, plantillas de procesamiento, etc. lleva tiempo. Hacer cualquiera de estas cosas en el mismo hilo que el bucle de evento principal del servidor evitará que el bucle continúe hasta que haya terminado.

+1

Gracias por la respuesta rápida. Considero que no bloquear significa que mientras una solicitud está esperando a ser procesada, otra está siendo procesada ya que las operaciones del servidor web son asincrónicas. Sin embargo, en este caso, si 9.999 usuarios están solicitando una página semi-estática, y una solicita una página de consulta de larga ejecución, los 9.999 usuarios tendrán que esperar al único usuario. – ipartola

+0

Entonces, si quiero tener acceso de base de datos no bloqueante en mi aplicación web, ¿cómo lo lograría con Tornado? – Chetan

+0

No es así. Agrega más instancias de Tornado y carga el balance entre ellos. Sus consultas DB no deben tomar * that * long; de lo contrario, eso oculta algún otro problema de diseño y/o operación. – z8000

0

Sí; este no es un servidor web completamente sin bloqueo.

Un servidor web sin bloqueo no bloquea, utilizando las API no bloqueantes para el archivo de E/S, el acceso de base de datos, y así sucesivamente, para asegurar que una solicitud que tiene que esperar a que algo para terminar no impide que otra solicitudes de ser procesadas. Esto se aplica a todo que pueda bloquear el servidor, incluido el acceso a la base de datos.

No hay nada tan tonto como "violación de la causalidad" en tener acceso sin bloqueo de base de datos; tiene mucho sentido ejecutar una consulta no bloqueante relacionada con una solicitud y procesar otras solicitudes mientras aún se está ejecutando. En la práctica, esto generalmente significará hacer conexiones múltiples al back-end de la base de datos.

Tenga en cuenta que si usted está tratando de ejecutar diez mil solicitudes simultáneas, tenga cuidado: la mayoría de los backends de bases de datos no pueden hacer frente a esto. Si tiene más de unas pocas docenas de solicitudes de bases de datos para ejecutar en paralelo, es probable que desee algo así como una agrupación de conexiones, para permitir que el servidor web haga muchas conexiones de bases de datos sin saturar el back-end. Esto hará que las solicitudes se bloqueen, esperando en una cola para obtener acceso a la base de datos, pero hacerlo de esta manera significa que no está bloqueando todo el servidor, solo las solicitudes que necesitan la base de datos.

+15

Estás hablando de algo que no entiendes del todo. El servidor web Tornado no bloquea. Si eliges usar el envoltorio fino opcional de Tornado _framework_ en MySQLdb, puedes perjudicar los beneficios de un servidor web no bloqueante, pero eso no dice absolutamente nada sobre el servidor web en sí mismo, del cual el módulo de base de datos no forma parte. –

+0

@Nicholas Knight: No, entiendo completamente lo que significa un "marco de servidor web no bloqueante" (vuelva a leer el OP); obviamente, tu no. –

33

tornado es no bloqueante, si escribe código de no bloqueo en la parte superior si, por ejemplo. usando el decorador asyncmongo y @tornado.web.asynchronous. Tornado como marco proporciona herramientas para eso.

Bret Taylor, uno de los autores originales, writes:

Hemos experimentado con diferentes enfoques asíncrono DB, pero se decidió por síncrono a FriendFeed, porque generalmente si nuestras consultas de base de datos se backlogging nuestras peticiones, nuestras backends no se pudo escalar a la carga de todos modos.Las cosas que fueron lo suficientemente lentas fueron abstraídas para separar los servicios backend que obtuvimos de manera asincrónica a través del módulo async HTTP .

Es cierto que Tornado no incluye una capa de base de datos no bloqueante; de hecho, la capa de la base de datos no es parte integral del marco de Tornado, a diferencia de, por ejemplo, ORM de Django. Sí, Tornado incluye el bloqueo del contenedor de MySQL porque eso es lo que FriendFeed utilizó, pero es más una biblioteca externa que una funcionalidad principal. Estoy bastante seguro de que la mayoría de la gente está usando algo más para acceder a la base de datos.