Медленная и частая PostgreSQL загрузка соединения с базой данных в Rails API - PullRequest
1 голос
/ 31 марта 2020

У меня есть Rails API с базой данных PostgreSQL.

Некоторые запросы к API показывают странное поведение, которое не зависит от конечной точки.

Эти запросы (около 5 -10% от общего числа запросов) начинаются с тех же 7 запросов к базе данных:

  • SET client_min_messages TO?
  • SET standard_conforming_strings = on
  • SET SESSION timezone TO?
  • SELECT t.oid, t.typname FROM pg_type WHERE t.typname IN (?) ...

Запуск запроса также занимает много времени, прежде чем будут выполнены 7 запросов. .

Кажется, это адаптер базы данных, инициирующий соединение. ActiveRecord :: ConnectionAdapters :: PostgreSQLAdapter

Это значительно замедляет запрос.

Я использую экземпляр Postegre SQL 11.6 AWS RDS с параметрами по умолчанию .

Вот мой конфиг database.yml:

default: &default
  adapter: postgresql
  encoding: unicode
  username: *****
  password: *****
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

production:
  <<: *default
  database: *****
  username: *****
  password: *****
  pool: 50

Как уменьшить количество инициирующих соединений? Есть ли способ кешировать запросы?

Спасибо,

1 Ответ

1 голос
/ 20 апреля 2020

Натолкнулся на то же самое, и вот что, я думаю, происходит:

Каждый раз, когда создается новое соединение, он выполняет запросы начальной загрузки, о которых вы упоминали выше. Предполагая, что новый процесс не порожден, необходимо создать новое соединение, так как ActiveRecord перезапустил существующие соединения.

По умолчанию ConnectionPool::Reaper отключит все соединения, которые простаивали более 5 минут. , См .: https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html

Если ваш API не получает никаких запросов в течение 5 минут, и все соединения повторяются, следующий запрос должен будет создать новое соединение и, следовательно, выполнить запросы.

Как уменьшить число инициирующих соединений?

Вы можете установить idle_timeout из 0 в database.yml. Это помешает ActiveRecord повторять соединения, но потенциально может вызвать проблемы в зависимости от того, сколько процессов запущено и какое у вас значение PG max_connections.

Есть ли способ кэшировать запросы?

Есть закрытая проблема, которая говорит об этом, но не похоже, что это можно кэшировать сегодня. https://github.com/rails/rails/issues/35311

...