Высокие издержки инициализации SQLAlchemy - PullRequest
0 голосов
/ 12 июня 2018

В настоящее время мы используем Flask RQ вместе с Flask SQLAlchemy и сталкиваемся с некоторыми проблемами с производительностью.Вот наша высокоуровневая архитектура:

  1. Конечная точка API достигнута
  2. Трудоемкие задачи помещаются в очередь в RQ
  3. Рабочий RQ создает новый процесс для выполнения задания
  4. Задание обычно состоит из запроса к базе данных с помощью Flask SQLAlchemy + дополнительная обработка

Если посмотреть на производительность (4) с помощью cProfile, я вижу

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?Я работаю на экземплярах AWS xlarge на 70% CPU.Все мои отношения загружаются динамически, используя lazy='dynamic', и соответствующий запрос занимает <10 миллисекунд, согласно pg_stat_statements. </li>
  2. Если предположить, что нет способа обойти (1), другой способ избежать постоянных издержек состоит в том, чтобыочередь вроде эта .Таким образом, вместо того, чтобы создавать новый процесс для каждого задания, задание запускается непосредственно в потоке.Это целесообразно для распределенных систем?Я не смог найти фреймворк, который сделал это, так что, может быть, это не очень хорошая идея?

Последнее замечание: если я глуп и не вижу очевидного решения, пожалуйста, дайте мнезнаю!

1 Ответ

0 голосов
/ 12 июня 2018

configure_mappers обычно вызывается только один раз за время существования приложения.Он настраивает внутреннюю бухгалтерию, чтобы сделать ваши модели пригодными для использования.Вы должны избегать его запуска для каждого разветвленного процесса.Для этого вызовите его вручную один раз в родительском процессе перед разветвлением:

from sqlalchemy.orm import configure_mappers

configure_mappers()
...