为在Gunicorn上运行的Flask-SQLAlchemy应用选择数据库pool_size

问题描述 投票:2回答:2

[我有一个在Gunicorn中运行的Flask-SQLAlchmey应用程序已连接到PostgreSQL数据库,但是我很难确定pool_size值应该是多少以及应该期望多少个数据库连接。

这是我对事物运作方式的理解:

  • Python 3.7中的进程不共享内存
  • 每个独角兽工人都是自己的过程
  • 因此,每个Gunicorn工作者都会获得它自己的数据库连接池副本,并且不会与任何其他工作者共享
  • Python DO中的线程共享内存
  • 因此,Gunicorn worker中的任何线程都将共享数据库连接池

到目前为止正确吗?如果正确,那么对于在Gunicorn中运行的同步Flask应用程序:

  • 最大数据库连接数是否等于(工作程序数)*(每个工作程序机的线程数?]
  • 并且在一个工作人员中,它使用池中的连接是否会超过工作人员?

pool_size是否应大于线程数是有原因的吗?那么,对于以gunicorn --workers=5 --threads=2 main:app启动的Gunicorn应用程序,pool_size应该为2吗?如果我仅使用工作程序而不使用线程,是否有任何理由要使pool_size大于1?

python database sqlalchemy flask-sqlalchemy gunicorn
2个回答
0
投票

我想你的理解很好。单个WSGI工作线程中的线程确实将共享一个连接池。因此,理论上数据库连接的最大数量为(number of workers) * N,其中N = pool_size + max_overflow。 (我不确定Flask-SQLAlchemy将max_overflow设置为什么,但这在这里是等式的重要部分-含义是the QueuePool documentation。)

实际上,如果您仅使用Flask-SQLAlchemy提供给您的线程范围的会话,则每个线程最多只能有一个连接;因此,如果您的线程数小于N,则您的上限确实为(number of workers) * (number of threads per worker)


0
投票

加上我的2美分。您的理解是正确的,但需要考虑以下几点:

  • 如果您的应用程序受IO限制(例如,与数据库对话),则您确实希望拥有多个线程。否则,您的CPU将永远无法达到100%的利用率。您通常需要使用负载测试工具来测试线程数以获得正确的配置,并比较每秒请求和CPU利用率。

  • 记住工作程序数量和连接之间的关系,您可以看到,在更改工作程序数量时,需要调整最大池大小。这可能很容易忘记,所以也许一个好主意是将池的大小设置为稍大于工人的数量,例如该数字的两倍。

  • postgresql为每个连接创建一个进程,并且当您有很多gunicorn进程时可能无法很好地扩展。我会在您的应用程序和数据库之间建立一些连接池(我猜pgbouncer是最受欢迎的连接池)。

© www.soinside.com 2019 - 2024. All rights reserved.