【问题标题】:Cannot set pool size for Flask_sqlalchemy无法为 Flask_sqlalchemy 设置池大小
【发布时间】:2018-10-26 16:38:28
【问题描述】:

我想将 sqlalchemy 池大小设置为默认值以外的值。

我有一个烧瓶应用程序。 我使用从文件文件中设置配置 app.config.from_pyfile('config.py')

就在我初始化数据库之前,我已经转储了配置,其中包括:

'SQLALCHEMY_DATABASE_URI': 'mysql://readonly:password@localhost/xyz',
'SQLALCHEMY_ECHO': False,
'SQLALCHEMY_MAX_OVERFLOW': 0,
'SQLALCHEMY_POOL_SIZE': 1,
'SQLALCHEMY_RECORD_QUERIES': False,
'SQLALCHEMY_TRACK_MODIFICATIONS': False, 

在加载配置并进行转储后,我们正在调用一些代码,例如:

db: SQLAlchemy = SQLAlchemy()
db.init_app(app)

我在 apache 上使用 mod_python 运行它,带有一个进程和一个线程。 我在 httpd.conf 中使用这个

WSGIDaemonProcess browse user=busybody group=busybody processes=1 threads=1 lang='en_US.UTF-8' locale='en_US.UTF-8' python-home=/users/x/virtualenvs/browse-wfalcMKM home=/users/x/browse
WSGIScriptAlias /abs /users/e-prints/browse/wsgi.py/abs

然后我用 siege 和 100 个并发连接来锤击它。

我在 mysql SHOW PROCESSLIST 中为用户“只读”获取了 20 个进程;我希望看到的是 SHOW PROCESSLIST 中用户“只读”的 1 个进程;

没有其他应用程序使用用户“只读”,当我停止 httpd/python/flask 应用程序时,SHOW PROCESSLIST 中的“只读”用户为零;

我希望按照我在此处的文档中尝试的方式进行配置:http://flask-sqlalchemy.pocoo.org/2.3/config/

我正在使用 python 3.6 和 mysql 5.1.73。看来我有 Flask_SQLAlchemy 2.3.2、mysqlclient 1.3.13 和 SQLAlchemy 1.2.12。这是在linux上。 Apache 与 mod-wsgi 4.5.15。

更新:

我添加了一个调试,我看到 db.engine.pool.size 设置为我期望的值。

我不确定这是否应该是这样工作的,但我发现我在不同的请求中得到了不同的池对象:

[Mon Oct 29 12:17:25 2018]  - ERROR: "pool size = 1"
[Mon Oct 29 12:17:25 2018]  - ERROR: "engine object = Engine(mysql://browse_readonly:***@localhost/arXiv?charset=utf8)"
[Mon Oct 29 12:17:25 2018]  - ERROR: "pool object = <sqlalchemy.pool.QueuePool object at 0x7f2342b97da0>"

[Mon Oct 29 12:17:35 2018]  - ERROR: "pool size = 1"
[Mon Oct 29 12:17:35 2018]  - ERROR: "engine object = Engine(mysql://browse_readonly:***@localhost/arXiv?charset=utf8)"
[Mon Oct 29 12:17:35 2018]  - ERROR: "pool object = "sqlalchemy.pool.QueuePool object at 0x7f2342b39400>"

更新 2:我正在使用 apache 和 mod-python。我将其添加到上述问题的正文中。 更新 3:我的错误,我们使用的是 mod-wsgi。

【问题讨论】:

  • 你使用的是什么 WSGI 服务器?我怀疑您使用的服务器使用子进程进行扩展,因此每个子进程都有自己的池

标签: python python-3.x flask sqlalchemy flask-sqlalchemy


【解决方案1】:

您正确设置了池大小。但您几乎可以肯定有多个独立的 WSGI 进程

我不确定这是否应该是这样工作的,但我发现我在不同的请求中得到了不同的池对象:

[...]  
[Mon Oct 29 12:17:25 2018]  - ERROR: "pool object = <sqlalchemy.pool.QueuePool object at 0x7f2342b97da0>"

[...]
[Mon Oct 29 12:17:35 2018]  - ERROR: "pool object = "sqlalchemy.pool.QueuePool object at 0x7f2342b39400>"

Flask-SQLAlchemy 在每个 Flask 应用程序设置中使用一个简单的单引擎和一个池,这是通过拥有多个 Flask 实例来拥有多个 QueuePool 实例的唯一方法,除了更奇特的多应用设置意味着您在多进程 WSGI 服务器中为应用提供服务。

WSGI 服务器通常使用多个工作进程以及线程来扩展性能。每个工作进程都是独立的,并且有自己的Flask 实例,每个实例都有自己的 SQLAlchemy 引擎和池。这取决于您将如何将其配置为仅使用线程的确切 WSGI 服务器。

单独的进程需要自己的 MySQL 连接是正常的。

【讨论】:

  • 我们正在使用 mod-python 和 apache prefork。
  • 其实是mod-wsgi 4.5.15。
  • @BrianC.: Apache pre-fork 创建新进程,但这取决于你的 mod_wsgi 配置有多少实际的 WSGI 进程;例如是否设置了WSGI daemon process。无论如何,每个单独的进程都必须有自己的 MySQL 连接。
【解决方案2】:

绝对可以在创建引擎的时候设置CONNECTION_POOL_SIZE

app.config['SQLALCHEMY_POOL_SIZE'] = 1
db = SQLAlchemy(app)

这可以确认已经使用

print("pool size = {}".format(db.engine.pool.size()))

某些配置参数在引擎创建后无法更改,因此问题可能是您使用db = SQLAlchemy() 创建引擎,然后再应用配置。然而这并不是全部,因为默认池大小为 5,如果您看到 20 个并发连接,则必须有其他内容。

【讨论】:

  • 据我所知,连接数的 20 来自溢出的 10(SQLAlchemy 的默认值)和 Flask_SQLAlchemy 在 apply_driver_hacks() 中为 mysql 驱动程序设置的池大小为 10。
  • 我添加了一个调试语句,我得到了我期望的大小。目前这是 1。我正在使用两个进程、三个线程、池大小 1 和溢出 0 运行,我看到超过 30 个与数据库的连接。我希望有 2 个连接。所以我仍然不确定如何让它工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-14
  • 1970-01-01
  • 2014-10-10
  • 2012-04-30
  • 2012-01-31
  • 1970-01-01
相关资源
最近更新 更多