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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为在Gunicorn上运行的Flask-SQLAlchemy应用选择数据库pool_size相关的知识,希望对你有一定的参考价值。

[我有一个在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?

答案

我想你的理解很好。单个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)

另一答案

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

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

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

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

以上是关于为在Gunicorn上运行的Flask-SQLAlchemy应用选择数据库pool_size的主要内容,如果未能解决你的问题,请参考以下文章

在 http 和 https 上运行 Gunicorn

为啥在 gunicorn 上运行的烧瓶应用程序中使用日志轮换时同时在多个文件上写入日志?

无法在 gunicorn wsgi 服务器上运行烧瓶应用程序

如何在 docker 上运行 gunicorn

尝试使用 Foreman 在 Gunicorn 上本地运行 Django 应用程序

如何运行多个Django App Gunicorn systemd?