高SQLAlchemy初始化开销

时间:2018-06-12 17:37:56

标签: python flask sqlalchemy flask-sqlalchemy python-rq

我们目前正在使用Flask RQ和Flask SQLAlchemy,并遇到一些性能问题。这是我们的高级架构:

  1. 点击了API端点
  2. 耗时的任务排队进入RQ
  3. RQ工作人员执行新流程以执行工作
  4. 作业通常包括通过Flask SQLAlchemy +附加处理的数据库查询
  5. 当使用cProfile查看(4)的性能时,我看到了

    1       5.7e-05     5.7e-05     4.064   4.064   __init__.py:496(__get__)
    535/1   0.002901    0.002901    3.914   3.914 base.py:389(_inspect_mapped_class)
    1       0.001281    0.001281    3.914   3.914   mapper.py:2782(configure_mappers)
    462/1   0.000916    0.000916    3.914   3.914   base.py:404(class_mapper)
    1       1.4e-05     1.4e-05     3.914   3.914   mapper.py:1218(_configure_all)
    59      0.01247     0.0002113   3.895   0.06601 mapper.py:1750(_post_configure_properties)
    985/907 0.01748     1.927e-05   3.29    0.003627    interfaces.py:176(init)
    235/157 0.00914     5.822e-05   3.162   0.02014 relationships.py:1650(do_init)
    ...
    

    enter image description here

    我看到很多时间花在SQLAlchemy上;我认为这是将SQL数据映射到ORM对象的一些开销。所以,我有两个问题:

    1. 是否需要花费大量时间来初始化SQL-ORM映射?我在70%CPU的AWS xlarge实例上运行。使用lazy='dynamic'动态加载我的所有关系,并且相应的查询采用< 10毫秒,根据pg_stat_statements。
    2. 假设无法解决(1),另一种避免持续开销的方法是拥有像this这样的队列。因此,作业不是为每个作业分配新进程,而是直接在线程中运行。这对分布式系统是否可行?我无法找到这样做的框架所以也许这不是一个好主意?
    3. 最后请注意,如果我是愚蠢而没有看到明显的解决方案,请告诉我!

1 个答案:

答案 0 :(得分:3)

configure_mappers通常仅在应用程序的生命周期内调用一次。它设置了一些内部簿记,使您的模型可用。您应该避免为每个分叉进程运行它。为此,请在分叉之前在父进程中手动调用一次:

from sqlalchemy.orm import configure_mappers

configure_mappers()