Python中最好的数据库连接池解决方案是什么?
我开发了一些自定义的类似数据访问对象(DAO)的类,以满足我项目中一些非常特殊的需求。这个项目是一个服务器端的进程,并不在任何框架内部运行。
这个解决方案运行得很好,但每次有新的请求时,我都会通过 MySQLdb.connect 打开一个新的连接。
我想知道在 Python 中,最好的“直接替换”方案是什么,以便使用连接池。我想要的效果有点像 Java 中的 commons DBCP 解决方案。
这个进程是长时间运行的,并且有很多线程需要发出请求,但并不是所有线程都会同时发出请求……具体来说,它们在写出一部分结果之前,会进行相当多的工作。
补充说明:经过进一步的搜索,我找到了 anitpool.py,看起来不错,但由于我对 Python 还比较陌生,我只是想确认一下我是否错过了更明显、更符合习惯或更好的解决方案。
9 个回答
把你的连接类封装起来。
给你能建立的连接数量设个上限。
返回一个未使用的连接。
在关闭连接的时候拦截一下,以便释放这个连接。
更新:我在 dbpool.py 里加了类似这样的东西:
import sqlalchemy.pool as pool
import MySQLdb as mysql
mysql = pool.manage(mysql)
在MySQL中?
我建议你别费心去搞连接池。连接池常常会带来麻烦,而且在MySQL中,它们并不会给你带来你期待的性能提升。这个话题可能会让人觉得很复杂,因为很多人会在这里提到各种最佳实践和教科书上的说法,讲连接池的好处。
连接池其实就是在无状态的应用(比如HTTP协议)和有状态的长时间运行的批处理应用之间搭建的一座桥。以前在网络出现之前,数据库连接是非常昂贵的(因为当时没人太在意连接建立需要多长时间),所以网络之后的应用才想出了连接池的方案,这样每次请求就不会给关系数据库带来巨大的处理负担。
而MySQL更像是一个网络时代的关系数据库,连接非常轻量且快速。我写过很多高流量的网络应用,根本不需要使用MySQL的连接池。
如果没有什么政治上的障碍,你可以考虑不使用连接池,这样可能会让事情变得简单一些。
在我看来,"更明显/更符合习惯/更好的解决方案"是使用现有的ORM,而不是自己去发明类似DAO的类。
我觉得ORM比“原始”的SQL连接更受欢迎。为什么呢?因为Python本身就是面向对象的,而把SQL中的一行数据映射到一个对象是非常重要的。实际上,处理SQL行而不把它们映射到Python对象的情况并不多。
我认为SQLAlchemy或SQLObject(以及相关的连接池)是更符合Python习惯的解决方案。
连接池作为一个单独的功能并不常见,因为纯SQL(没有对象映射)在复杂且长时间运行的过程中并不太受欢迎,而这些过程是可以从连接池中受益的。确实,纯SQL是会被使用,但通常是在一些简单或可控的应用中,这种情况下连接池并没有太大帮助。
我觉得你可能有两个选择:
- 修改你的类,使用SQLAlchemy或SQLObject。虽然一开始看起来很痛苦(感觉之前的工作都白费了),但你应该能够利用之前的设计和思考。这只是一个采用广泛使用的ORM和连接池解决方案的练习。
- 自己实现一个简单的连接池,按照你之前提到的算法来做——使用一个简单的集合或列表来循环使用连接。