Domanda

Tornado si pubblicizza come "relativamente semplice, quadro non-blocking web server" creata per risolvere il problema C10K. Tuttavia, guardando il loro involucro di database, che avvolge MySQLdb, mi sono imbattuto nel seguente pezzo di codice:

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

Per quanto ne so chiamate al MySQLdb, che è costruito in cima libmysqlclient, bloccano.

Ho ragione di pensare che una query a lungo in esecuzione renderebbe l'intero server Tornado non risponde fino a quando non finisce o c'è magia sul codice?

È stato utile?

Soluzione

Sì, assenti le altre misure, il server attenderà per la query per terminare l'esecuzione. Ciò non significa Tornado non è un non-blocking web server.

A "server non-blocking web" non blocca sulla rete di I / O (e può avere un po 'di fondo del disco I / O se lo fa file statico porzione). Ciò non significa che si ottiene istante, la causalità-violando l'esecuzione delle istruzioni nell'applicazione.

Fare una chiamata al database richiede tempo, proprio come la lettura dei file, formattare le stringhe, l'elaborazione di modelli, ecc richiede tempo. Fare una qualsiasi di queste cose nello stesso thread come ciclo evento principale del server impedirà il ciclo di muoversi fino a quando il gioco è fatto.

Altri suggerimenti

Tornado non è bloccante se si scrive il codice non-blocking in cima se, ad es. utilizzando asyncmongo e @ tornado.web.asynchronous decoratore. Tornado come quadro fornisce strumenti per questo.

Bret Taylor, uno degli autori originali, scrive :

  

Abbiamo sperimentato diversi asincrono DB si avvicina, ma optato per   sincrono a FriendFeed perché in genere se le nostre richieste erano DB   backlogging le nostre richieste, le nostre backend non potevano scalare per il carico   Comunque. Le cose che erano abbastanza lenti sono stati estratti per separare   backend servizi che abbiamo recuperato in modo asincrono tramite l'async HTTP   modulo.

E 'vero che Tornado non include uno strato non-blocking del database; infatti lo strato database non è parte integrante del quadro ciclone affatto, al contrario di esempio ORM di Django. Sì, navi Tornado con il blocco MySQL involucro perché è quello che è successo FriendFeed uso, ma è più una libreria esterna di funzionalità di base. Sono abbastanza sicuro che la maggior parte delle persone utilizzano qualcos'altro per l'accesso al database.

Tornado è non bloccante , ma solo limitato ad alcune operazioni IO come leggere o scrivere un file di socket.

se si desidera che tutto nella vostra non bloccante codice, è necessario progettare da yourself.but se il codice è di calcolo intensivo, quindi non bloccante è privo di significato per voi. questa situazione si potrebbe utilizzare multi-processo.

ricordare una cosa non bloccante significa solo il server di invio / ricezione data non sarà il blocco. Se non è possibile rendere il codice non bloccante, quindi tutta l'applicazione è in qualche modo il blocco.

Sì; questo non è un server web completamente non bloccante a tutti.

Un server web non bloccante non bloccare, utilizzando le API non bloccanti per il file di I / O, l'accesso al database, e così via, al fine di garantire che una richiesta che deve aspettare che qualcosa alla fine non impedisce altre richieste dalla fase di elaborazione. Questo vale per tutto che potrebbero bloccare il server, tra cui l'accesso al database.

Non c'è niente di tanto sciocco quanto "violazione della causalità" nell'avere non bloccante accesso al database; ha perfettamente senso di eseguire una query non-blocking relativi a una richiesta, e per elaborare altre richieste, mentre che è ancora in esecuzione. In pratica, questo di solito significa rendere più connessioni al database back-end.

Si noti che se si sta cercando di eseguire decine di migliaia di richieste simultanee, fate attenzione: la maggior parte dei database backend non possono far fronte a questo. Se si dispone di più di qualche decina di richieste di database per l'esecuzione in parallelo, probabilmente si desidera qualcosa di simile a un Pooler collegamento, per consentire al server Web per fare un sacco di connessioni al database, senza inondare il backend. Questo farà sì che le richieste di blocco, in attesa in una coda per ottenere l'accesso al database, ma farlo in questo modo significa che non sta bloccando l'intero server -. Solo le richieste che necessitano il database

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top