python中的MySQL连接池?

Posted

技术标签:

【中文标题】python中的MySQL连接池?【英文标题】:MySQL connection pool in python? 【发布时间】:2018-09-03 10:50:22 【问题描述】:

我正在尝试使用 Python 处理大量数据并在 mysql 中维护处理状态。但是,我很惊讶没有标准的 python-mysql 连接池(如 Java 中的 HikariCP)。

我最初是从 PyMySQL 开始的,在程序运行前几个小时之前一切都很好。几个小时后,事情开始失败。我遇到了很多错误,例如:

pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on '127.0.0.1' ([Errno 99] Cannot assign requested address)")

此外,由于缺少连接池,我打开和关闭连接过于频繁,导致很多端口卡在 TIME_WAIT 状态

/d/p/950 ❯❯❯ netstat -nt | wc -l
84752

根据 this 和 this,我尝试设置 tcp_fin_timeout 和 ip_local_port_range,但几乎没有任何改进。

echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 15000 65000 > /proc/sys/net/ipv4/ip_local_port_range

然后我发现MySQL提供了带有pooling功能的mysql.connector。在做了所有这些之后,性能实际上恶化了。更多进程开始失败。我正在使用 Python 的 multiprocessing 模块在 24 核机器上同时运行 29 个进程(multiprocessing.Pool 默认选择这个 no)。以下是代码,当然我是使用 .my.cnf 来传递所有凭据以避免将它们提交给 git :

    import mysql.connector
    from mysql.connector import pooling
    conn_pool = pooling.MySQLConnectionPool(pool_name="mypool1",
                                              pool_size=pooling.CNX_POOL_MAXSIZE,
                                              option_files=MYSQL_CONFIG,
                                              option_groups=MYSQL_GROUP_NODE1,
                                              allow_local_infile=True)
conn = conn_pool.get_connection()

最后,恢复到旧代码。仍在使用 PyMySQL,尽管错误频率较低,但它仍然会导致重大问题。我查看了 SQLAlchemy,并没有真正找到很多关于池的文档。

我想知道其他人是如何处理 mysql-python 连接池问题的?我真的相信应该有一些东西,这样我就不必重新发明***。

任何指针都非常感谢。

【问题讨论】:

【参考方案1】:

DBUtils 实现 MySQL(并且通常声称支持任意 DB-API 2 兼容的数据库接口)用户大小的连接池 PooledDB、thead-mapped 池 PersistentDBSteadyDB(参见 functionality section)。后者应该适合您的情况,其中multiprocessing.Pool 创建每个具有托管持久数据库连接的工作进程。它被描述为:

DBUtils.SteadyDB 是一个基于任何 DB-API 2 数据库模块建立的普通连接实现与数据库的“强化”连接的模块。当“强化”连接已关闭或数据库连接已丢失或使用频率超过可选使用限制时,它会在访问时透明地重新打开。

您可以将它与 PyMySQL 一起使用,例如:

import pymysql
from DBUtils.SteadyDB import connect

db = connect(
  creator = pymysql, # the rest keyword arguments belong to pymysql
  user = 'guest', password = '', database = 'name', 
  autocommit = True, charset = 'utf8mb4', 
  cursorclass = pymysql.cursors.DictCursor)

有关更多示例,另请参阅this related question。

【讨论】:

感谢您的回答。这对我来说看起来很有希望。让我试试看它是否有效。如果您遇到任何其他示例,请分享。再次感谢!

以上是关于python中的MySQL连接池?的主要内容,如果未能解决你的问题,请参考以下文章

Python实现Mysql数据库连接池

Python mysql连接池

python mysql Connect Pool mysql连接池 (201

python 基础-- 使用 MySQLdb 操作 MySQL 或使用连接池 DBUtils.PooledDB 操作 MySQL

python 基础-- 使用 MySQLdb 操作 MySQL 或使用连接池 DBUtils.PooledDB 操作 MySQL

在 mysql-connector-python 中结束连接池