2010-09-03 2 views
19

Tornado рекламирует себя как «относительно простой, неблокирующий веб-серверный фреймворк» и был разработан для решения проблемы C10k. Однако, глядя на их обертке базы данных, которая оборачивает MySQLDb, я наткнулся на следующий фрагмент кода:Действительно ли Торнадо не блокирует?

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 

Насколько я знаю, звонки на MySQLdb, который построен на вершине libmysqlclient, блокируют.

Я правильно понял, что долговременный запрос сделает весь сервер Tornado невосприимчивым до тех пор, пока он не закончится или не будет волшебства в коде?

+2

Что вы ожидаете? Неблокирование не означает, что «все строки запускаются одновременно». – zneak

+6

-1 за неправильный ответ; неблокирующий веб-сервер не должен блокировать запросы из-за доступа к базе данных (доступа к диску) для других запросов. –

+1

Я ценю комментарий, но я считаю, что принял ответ, который касается моего вопроса: будет ли использование оболочки MySQL сделать весь серверный блок. Ответ кажется: да, будет. Tornado не предоставляет пул процессов для общения с MySQL, поэтому он блокирует. Ваш ответ тоже имеет смысл, но Николас был здесь первым. – ipartola

ответ

16

Да, при отсутствии других мер сервер будет ожидать завершения выполнения запроса. Это не означает, что Tornado не является неблокирующим веб-сервером.

«Неблокирующий веб-сервер» не блокирует сетевые операции ввода-вывода (и может иметь некоторое положение для ввода/вывода на диск, если он выполняет статический файл). Это не означает, что вы получаете мгновенное, нарушение причинно-следственной инструкции в вашем приложении.

Выполнение вызова базы данных требует времени, как чтение файлов, форматирование строк, обработка шаблонов и т. Д. Требует времени. Выполнение любой из этих вещей в том же потоке, что и основной цикл событий сервера, предотвратит движение цикла до тех пор, пока вы не закончите.

+1

Спасибо за быстрый ответ. Я беру без блокировки, чтобы означать, что, пока один запрос ожидает обработки, другой обрабатывается, так как операции веб-сервера асинхронны. В этом случае, хотя, если 9999 пользователей запрашивают полустатистическую страницу и один запрашивает длинную страницу запроса, 9999 пользователям придется ждать одного пользователя. – ipartola

+0

Итак, если я хочу иметь неблокирующий доступ к базе данных в своем веб-приложении, как бы добиться этого с помощью Tornado? – Chetan

+0

У вас нет. Вы добавляете больше экземпляров Tornado и балансируете баланс между ними. Ваши запросы в БД не должны принимать * это * долго; в противном случае это противоречит какой-либо другой проблеме дизайна и/или ops. – z8000

0

Да; это вовсе не полностью неблокирующий веб-сервер.

Неблокирующий веб-сервер не блокирует, используя неблокирующие API для ввода-вывода файлов, доступа к базе данных и т. Д., Чтобы гарантировать, что один запрос, который должен ждать чего-то, запросы от обработки. Это относится к всем, которые могут блокировать сервер, включая доступ к базе данных.

Нет ничего глупого, как «нарушение причинности» при наличии неблокирующего доступа к базе данных; имеет смысл запускать неблокирующий запрос, связанный с одним запросом, и обрабатывать другие запросы, пока они все еще работают. На практике это обычно означает создание нескольких соединений с базой данных базы данных.

Обратите внимание, что если вы пытаетесь выполнить десять тысяч одновременных запросов, будьте осторожны: большинство баз данных не могут справиться с этим. Если у вас более нескольких десятков запросов на базу данных, которые вы запускаете параллельно, вы, вероятно, хотите получить что-то вроде пула соединений, чтобы веб-сервер мог делать много соединений с базой данных, не опуская бэкэнд. Это вызовет блокировку запросов, ожидающих очереди, чтобы получить доступ к базе данных, но это означает, что это не блокирует весь сервер - просто запросы, которым нужна база данных.

+15

Вы обращаетесь к чему-то, чего не понимаете в полной мере. Веб-сервер Tornado не блокирует. Если вы решите использовать дополнительную тонкую оболочку Tornado _framework_ вокруг MySQLdb, вы можете повредить преимущества неблокирующего веб-сервера, но это абсолютно ничего не говорит о самом веб-сервере, который не является частью модуля базы данных. –

+0

@Nicholas Knight: Нет, я полностью понимаю, что такое «неблокируемая структура веб-сервера» (перечитайте OP); очевидно, вы этого не делаете. –

33

Торнадо не блокируется, если вы пишете неблокирующий код сверху, если он, например. используя asyncmongo и @tornado.web.asynchronous декоратор. Tornado в качестве основы предоставляет инструменты для этого.

Брет Тейлор, один из первых авторов, writes:

Мы экспериментировали с различными подходами асинхронной DB, но остановились на синхронно на FriendFeed, потому что в целом, если наши DB запросы были backlogging наши запросы, наши движки не может масштабироваться до нагрузки в любом случае.Вещи, которые были достаточно медленными, были абстрагированы, чтобы разделить бэкэнд-услуги, которые мы асинхронно выводили через модуль async HTTP .

Это правда, что Tornado не включает в себя неблокирующий уровень базы данных; на самом деле слой базы данных не является неотъемлемой частью структуры Tornado вообще, в отличие от, например, ORM Django. Да, Tornado поставляется с блокирующей оболочкой MySQL, потому что это то, что использовал FriendFeed, но это скорее внешняя библиотека, чем основная функциональность. Я уверен, что большинство людей используют что-то еще для доступа к базе данных.

Смежные вопросы