Ubuntu20.04环境下Django ORM访问远程PostgreSQL速度过慢问题咨询
访问速度合理性判定
这种耗时差异不属于正常情况。本地通过Unix套接字访问PostgreSQL本身比跨服务器TCP访问快,但同机房内网服务器之间的网络延迟通常在1ms以内,正常耗时差不会超过30%,你当前场景下耗时差达到3~4倍,多进程并发时还会进一步翻倍,说明存在其他性能瓶颈。
优化方案
先做根因排查
- 测细粒度网络指标:不要只测大文件传输带宽,用
ping测双向往返延迟,iperf3测小包吞吐,tcpdump抓包确认有没有TCP丢包、重传、慢启动问题,数据库交互多为小包传输,常规带宽测试覆盖不到这类场景的问题。 - 统计SQL查询次数:Django ORM很容易出现N+1查询问题,跨网络场景下每次查询的往返延迟会被叠加放大,本地延迟低所以感知不明显。可以用
django.db.connection.queries统计脚本执行的SQL总条数,通过select_related、prefetch_related优化批量查询,减少交互次数。 - 调整数据库日志定位慢查询:你当前配置的
log_min_duration_statement为10s,大部分短耗时的慢查询不会被记录,临时调整为100ms,对比业务服务器发起的查询和本地发起的查询在数据库端的实际执行耗时,排除SQL本身的执行效率问题。另外当前开启的log_connections、log_disconnections会增加短连接场景的额外开销,没有排查需求时可以关闭。
配置优化项
- 连接复用优化:如果你的脚本是短连接模式,频繁新建TCP连接的开销会被网络放大。Django侧可以在
settings.py中配置CONN_MAX_AGE参数,设置数据库连接的复用时长;pgBouncer要确认使用会话池模式,不要用事务池或语句池,避免和Django ORM的会话级状态依赖冲突。 - PostgreSQL网络配置优化:在
postgresql.conf中新增以下配置后重启服务:
另外你当前tcp_keepalives_idle = 30 tcp_keepalives_interval = 10 tcp_keepalives_count = 5 tcp_writesize = 8192 tcp_readsize = 8192max_connections设置为1000过高,PostgreSQL单连接约占用10MB内存,过多连接会挤占缓存空间,配合pgBouncer使用的话,把该参数降到200以内即可。 - 系统内核参数优化:在两台服务器的
/etc/sysctl.conf中新增以下配置,执行sysctl -p生效:
优化TCP缓冲区和时间等待连接复用,减少短连接开销。net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 net.ipv4.tcp_tw_reuse = 1
内容的提问来源于stack exchange,提问作者Фёдор Яковлев
相关产品推荐
相关产品推荐

