Django 持久数据库连接
我正在使用Django、Apache和mod_wsgi,以及PostgreSQL(它们都在同一台服务器上),我需要处理很多简单的动态页面请求(每秒有几百个)。我遇到的问题是,Django没有持久的数据库连接,每次请求都要重新连接(这大约需要5毫秒)。
在进行性能测试时,我发现使用持久连接时,我可以处理接近500个请求每秒,而不使用时只能处理50个请求每秒。
有没有人有什么建议?我该如何修改Django以使用持久连接,或者加快Python与数据库之间的连接速度呢?
7 个回答
在Django的主干代码中,找到并编辑 django/db/__init__.py
文件,把其中的一行注释掉:
signals.request_finished.connect(close_connection)
这个信号处理程序会导致每次请求后都与数据库断开连接。我不知道这样做会有什么副作用,但每次请求后重新建立连接是没有意义的;这会影响性能,正如你所注意到的。
我现在在用这个方法,但还没有做全面的测试来看看会不会出问题。
我不明白为什么大家都认为这需要新的后端或者特殊的连接池,或者其他复杂的解决方案。这看起来很简单,虽然我不怀疑最开始让他们这样做的原因可能有些复杂,但这些问题应该更合理地处理;每个请求增加5毫秒的开销对于高性能服务来说是相当多的,正如你所注意到的。(我自己需要 150毫秒,我还没搞清楚为什么。)
补充:另一个必要的改动是在 django/middleware/transaction.py 文件中;去掉两个 transaction.is_dirty() 的测试,始终调用 commit() 或 rollback()。否则,如果只从数据库读取数据,它就不会提交事务,这会导致一些应该关闭的锁保持打开状态。
试试 PgBouncer - 这是一个轻量级的连接池工具,专门用于PostgreSQL数据库。
它的特点有:
- 在切换连接时有几种不同的方式可以选择:
- 会话池
- 事务池
- 语句池
- 内存占用很低(默认每个连接只需要2KB)。
Django 1.6 新增了 持久连接支持(链接到最新稳定版Django的文档):
持久连接的好处是可以避免在每次请求时都重新建立与数据库的连接,这样可以节省时间和资源。这个功能是通过一个叫做 CONN_MAX_AGE 的参数来控制的,它定义了一个连接可以存活的最长时间。这个设置可以针对每个数据库单独调整。