当前位置:  开发笔记 > 编程语言 > 正文

python中数据库连接池的最佳解决方案是什么?

如何解决《python中数据库连接池的最佳解决方案是什么?》经验,为你挑选了4个好方法。

我已经开发了一些类似于DAO的自定义类来满足我的项目的一些非常专业的需求,这是一个服务器端进程,它不在任何类型的框架内运行.

解决方案很有效,除了每次发出新请求时,我都会通过MySQLdb.connect打开一个新连接.

什么是最好的"drop in"解决方案,将其转换为在python中使用连接池?我正在想象类似于Java的公共DBCP解决方案.

这个过程是长时间运行的,并且有很多线程需要发出请求,但不是所有的同时...特别是他们在写出一大块结果的短暂爆发之前做了很多工作.

编辑添加:经过一些搜索,我发现anitpool.py看起来不错,但由于我对python相对较新,我想我只是想确保我没有错过更明显/更惯用/更好的解决方案.



1> mbac32768..:

在MySQL?

我想说不要打扰连接池.它们通常是麻烦的源头,而MySQL则不会为您带来您希望的性能优势.这条道路可能需要付出很多努力 - 政治上 - 因为在这个空间里有很多关于连接池优势的最佳实践手动和教科书措辞.

连接池只是无状态应用程序(例如HTTP协议)的后Web时代与有状态长期批处理应用程序的前Web时代之间的桥梁.由于连接在预网络数据库中非常昂贵(因为没有人过多地关心建立连接需要多长时间),后网应用程序设计了这种连接池方案,因此每次访问都不会产生这种巨大的处理开销在RDBMS上.

由于MySQL更像是一个网络时代的RDBMS,因此连接非常轻巧和快速.我编写了许多高容量的Web应用程序,它们根本不使用连接池来处理MySQL.

只要不存在需要克服的政治障碍,这可能会使您从中受益.


这个答案发布8年后,汇集仍然保持相关性.如果您运行流量较大的Web应用程序,则无论其无状态如何,都可以轻松地遇到"Too many connections"限制.池将通过等待免费连接而不是硬故障来帮助缓解这种情况.此外,如果您想横向扩展您的应用服务器,您的数据库可能不会生活在同一台计算机上.在这种情况下,您很可能希望通过HTTPS连接到它,这会产生很大的开销.游泳池也会有所帮助.

2> Chris..:

包装你的连接类.

设置您建立的连接数限制.返回未使用的连接.拦截接近释放连接.

更新:我在dbpool.py中添加了这样的内容:

import sqlalchemy.pool as pool
import MySQLdb as mysql
mysql = pool.manage(mysql)


@Chris,通过这个逻辑链,我也应该开始自己实现我的哈希映射和列表.
克里斯,肯定有人已经建立了这个?最糟糕的情况我可以自己编写,但显然这对于​​不使用现有ORM /框架的人来说应该是一个相当普遍的要求,我相信其他人已经创建了一个已经过时间证明的解决方案?

3> S.Lott..:

IMO,"更明显/更惯用/更好的解决方案"是使用现有的ORM而不是发明类似DAO的类.

在我看来,ORM比"原始"SQL连接更受欢迎.为什么?因为Python OO,从SQL行到对象的映射绝对必要的.处理不映射到Python对象的SQL行的情况并不多.

我认为SQLAlchemy或SQLObject(以及相关的连接池)是更惯用的Pythonic解决方案.

池作为单独的功能并不常见,因为纯SQL(没有对象映射)对于受益于连接池的复杂,长时间运行的流程并不是非常流行.是的,纯粹的SQL 使用,但它总是在池是没有帮助的简单或多个控制应用中使用.

我想你可能有两种选择:

    修改您的类以使用SQLAlchemy或SQLObject.虽然这一开始显得很痛苦[所有浪费的工作],但您应该能够利用所有的设计和思想,而这只是采用广泛使用的ORM和汇集解决方案的练习.

    使用您概述的算法滚动您自己的简单连接池 - 您循环的简单Set或List连接.



4> metaperture..:

旧线程,但对于通用池(连接或任何昂贵的对象),我使用类似的东西:

def pool(ctor, limit=None):
    local_pool = multiprocessing.Queue()
    n = multiprocesing.Value('i', 0)
    @contextlib.contextmanager
    def pooled(ctor=ctor, lpool=local_pool, n=n):
        # block iff at limit
        try: i = lpool.get(limit and n.value >= limit)
        except multiprocessing.queues.Empty:
            n.value += 1
            i = ctor()
        yield i
        lpool.put(i)
    return pooled

哪些构造是懒惰的,有一个可选的限制,应该推广到我能想到的任何用例.当然,这假设你确实需要汇集任何资源,对于许多现代SQL喜欢的资源你可能不会这样.用法:

# in main:
my_pool = pool(lambda: do_something())
# in thread:
with my_pool() as my_obj:
    my_obj.do_something()

这确实假设ctor创建的任何对象在需要时都有适当的析构函数(某些服务器不会终止连接对象,除非它们被显式关闭).

推荐阅读
保佑欣疼你的芯疼
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有