Tornado Web Framework Mysql обработка соединений - PullRequest
5 голосов
/ 17 декабря 2009

Недавно я изучал веб-фреймворк Tornado, чтобы обслуживать множество согласованных соединений множеством разных клиентов.

У меня есть обработчик запросов, который в основном берет зашифрованную строку RSA и расшифровывает ее. Расшифрованный текст - это строка XML, которая анализируется обработчиком документов SAX, который я написал. Все отлично работает, и время выполнения (на HTTP-запрос) составляло примерно 100 миллисекунд (с расшифровкой и анализом).

XML содержит хэш имени пользователя и пароля пользователя. Я хочу подключиться к серверу MySQL, чтобы убедиться, что имя пользователя совпадает с хэшем пароля, предоставленным приложением.

Когда я добавляю в основном следующий код:

conn = MySQLdb.connect (host = "192.168.1.12",
                user = "<useraccount>",
                passwd = "<Password>",
                db = "<dbname>")
    cursor = conn.cursor()

    safe_username = MySQLdb.escape_string(XMLLoginMessage.username)
    safe_pass_hash = MySQLdb.escape_string(XMLLoginMessage.pass_hash)

    sql = "SELECT * FROM `mrad`.`users` WHERE `username` = '" + safe_username + "' AND `password` = '" + safe_pass_hash + "' LIMIT 1;"

    cursor.execute(sql)

            cursor.close()
    conn.close()

Время выполнения HTTP-запроса возрастает до 4 - 5 секунд! Я полагаю, что это происходит за время, необходимое для подключения к самому серверу базы данных MySql.

Мой вопрос: как я могу ускорить это? Могу ли я объявить соединение MySQL в глобальной области и получить доступ к нему в обработчиках запросов, создав новый курсор, или возникнут проблемы с параллелизмом из-за асинхронного проектирования Tornado?

Как правило, как мне не нужно устанавливать новое соединение с сервером MySQL КАЖДЫЙ запрос Http, поэтому для его реализации требуется всего лишь доля секунды вместо нескольких секунд.

Также обратите внимание, что сервер SQL фактически находится на том же физическом компьютере, что и экземпляр Tornado Web Server

Обновление

Я только что выполнил простой запрос MySQL через профилировщик, тот же код ниже.

Вызов функции 'connections.py' init занял 4,944 секунды для выполнения в одиночку. Это не кажется правильным, не так ли?

Обновление 2

Я думаю, что запуск с одним соединением (или даже с несколькими с очень простым пулом соединения с БД) будет достаточно быстрым для обработки пропускной способности, которую я ожидаю для каждого экземпляра веб-сервера торнадо.

Если 1000 клиентов нуждаются в доступе к запросу (типичное время запроса - тысячи секунд), самому неудачливому клиенту потребуется только одна секунда, чтобы получить данные.

Ответы [ 3 ]

1 голос
/ 17 декабря 2009

Рассмотрим SQLAlchemy , который обеспечивает более качественную абстракцию по сравнению с DBAPI, а также обеспечивает пул соединений и т. Д. (Вы можете с радостью проигнорировать его ORM и просто использовать SQL-инструментарий)

(Кроме того, вы не блокируете вызовы базы данных в асинхронных обработчиках запросов?)

1 голос
/ 17 декабря 2009

Соединение SQL не должно занимать 5 секунд. Постарайтесь не выдавать запрос и посмотрите, не улучшит ли это вашу производительность, - что должно.

Модуль Mysqldb имеет потокобезопасность «1», что означает, что модуль является потокобезопасным, но соединения не могут быть разделены между потоками. Вы можете реализовать пул соединений в качестве альтернативы.

Наконец, DB-API имеет форму замены параметров для запросов, которые не требуют ручной конкатенации запроса и экранирования параметров:

cur.execute("SELECT * FROM blach WHERE x = ? AND y = ?", (x,y))
0 голосов
/ 01 октября 2010

Объявите его в базовом обработчике, он будет вызываться один раз для каждого приложения.

...