【问题标题】:Tornado Web Framework Mysql connection handlingTornado Web 框架 Mysql 连接处理
【发布时间】:2010-12-27 13:27:49
【问题描述】:

我最近一直在探索 Tornado Web 框架,以便为许多不同的客户端提供大量一致的连接。

我有一个请求处理程序,它基本上采用 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 的异步设计而遇到并发问题?

基本上,我怎么能不必在每个 Http 请求中都产生与 MySQL 服务器的新连接,所以它只需要几分之一秒而不是几秒来实现。

另外,请注意,SQL Server 实际上与 Tornado Web Server 实例在同一台物理机器上

更新

我刚刚通过分析器运行了一个简单的 MySQL 查询,下面的代码相同。

单独执行对“connections.py”init 函数的调用需要 4.944 秒。这似乎不对,是吗?

更新 2

我认为使用一个连接(或者甚至几个使用非常简单的 DB 连接池)运行将足够快,可以处理我期望的每个 tornado Web 服务器实例的吞吐量。

如果 1,000 个客户端需要访问一个查询,典型的查询时间是数千秒,最不幸的客户端只需等待一秒钟即可检索数据。

【问题讨论】:

  • 5秒可能与数据库连接有关,与实际查询无关,如果您使用tornado,您可以全局连接到db,然后将db参数与请求一起传递。跨度>

标签: python mysql time tornado persistent-connection


【解决方案1】:

考虑SQLAlchemy,它提供了比DBAPI 更好的抽象,还提供了连接池等(您可以愉快地忽略它的ORM,只使用SQL 工具包)

(另外,您没有在异步请求处理程序中阻塞数据库调用?)

【讨论】:

  • 我知道我没有在上面的代码中进行阻塞调用,如果这就是你要问的,我只是没有在示例中包含任何内容。最终,会有,但连接时间是什么让我。我相信我会尝试一下 SQLAlchemy,所以感谢您的回答!
【解决方案2】:

SQL 连接不应花费 5 秒。尽量不要发出查询,看看这是否会提高您的性能 - 它应该这样做。

Mysqldb 模块的线程安全性为“1”,这意味着该模块是线程安全的,但不能在线程之间共享连接。您可以实现连接池作为替代方案。

最后,DB-API 有一个用于查询的参数替换表单,不需要手动连接查询和转义参数:

cur.execute("SELECT * FROM blach WHERE x = ? AND y = ?", (x,y))

【讨论】:

  • 好吧,我不知道自动参数化的东西,那真的很有帮助。明天我会考虑删除查询,看看这会给我带来什么影响。我想我最终将不得不编写一个连接池......只是因为对数据库的调用可能会阻塞其他线程。我是否决定这样做将在测试中。
【解决方案3】:

在基本处理程序中声明它,它将在每个应用程序中调用一次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多