django - pgbouncer 与 Django 的 CONN_MAX_AGE 的理想设置

标签 django connection-pooling pgbouncer

我正在运行一个 Multi-Tenancy 网站,我希望减少为每个请求创建 PostgreSQL 连接的开销。 Django 的 CONN_MAX_AGE 允许这样做,但代价是创建大量与 PostgreSQL 的开放空闲连接(8 个工作线程 * 20 个线程 = 160 个连接)。每个连接 10MB,这会消耗大量内存。

主要目的是减少连接时间开销。 因此我的问题是:

Django 1.6 设置:

DATABASES['default'] = {
    'ENGINE':   'django.db.backends.postgresql_psycopg2',

     ....

    'PORT': '6432'
    'OPTIONS': {'autocommit': True,},
    'CONN_MAX_AGE': 300,
}

ATOMIC_REQUESTS = False   # default

Postgres:

max_connections = 100

PgBouncer:

pool_mode = session     # Can this be transaction?
max_client_conn = 400   # Should this match postgres max_connections?
default_pool_size = 20
reserve_pool_size = 5

最佳答案

这是我使用过的设置。

pgbouncer 与 Gunicorn、celery 等在同一台机器上运行

pgbouncer.ini:

[databases]
<dbname> = host=<dbhost> port=<dbport> dbname=<dbname>

[pgbouncer]
: your app will need filesystem permissions to this unix socket
unix_socket_dir = /var/run/postgresql
; you'll need to configure this file with username/password pairs you plan on
; connecting with.
auth_file = /etc/pgbouncer/userlist.txt

; "session" resulted in atrocious performance for us. I think
; "statement" prevents transactions from working.
pool_mode = transaction

; you'll probably want to change default_pool_size. take the max number of
; connections for your postgresql server, and divide that by the number of
; pgbouncer instances that will be conecting to it, then subtract a few
; connections so you can still connect to PG as an admin if something goes wrong.
; you may then need to adjust min_pool_size and reserve_pool_size accordingly.
default_pool_size = 50
min_pool_size = 10
reserve_pool_size = 10
reserve_pool_timeout = 2
; I was using gunicorn + eventlet, which is why this is so high. It
; needs to be high enough to accommodate all the persistent connections we're
; going to allow from Django & other apps.
max_client_conn = 1000
...

/etc/pgbouncer/userlist.txt:

"<dbuser>" "<dbpassword>"

Django 设置.py:

...
DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.postgresql_psycopg2',
        'NAME': '<dbname>',
        'USER': '<dbuser>',
        'PASSWORD': '<dbpassword>',
        'HOST': '/var/run/postgresql',
        'PORT': '',
        'CONN_MAX_AGE': None,  # Set to None for persistent connections
    }
}
...

如果我没记错的话,你基本上可以与 pgbouncer 建立任意数量的“持久”连接,因为当 Django 处理完服务器连接后,pgbouncer 会将服务器连接释放回池中(只要你使用 transactionpool_mode语句)。当 Django 尝试重用其持久连接时,pgbouncer 负责等待与 Postgres 的可用连接。

关于django - pgbouncer 与 Django 的 CONN_MAX_AGE 的理想设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27418264/

相关文章:

python - 如何在负载均衡器后面使用 django-compressor?

sql - ADO.NET 池连接无法重用

pgbouncer - 是什么导致 pgbouncer 的 avg_wait_time > 0?

postgresql - pgBouncer池化类型的区别

mysql - OpenJPA + Tomcat JDBC 连接池 = 陈旧数据

postgresql - 你怎么知道 PGBouncer 是否正常工作?

python - 访问被拒绝 Django : (1045, "Access denied for user ' darth_vader' @'151.33.241.48'(使用密码:YES)")

Django - 显示 Action 进度

python - Django - 原始查询必须包含主键

java - 在 JBOSS 应用程序服务器下运行的 Java 应用程序中的数据库连接池