Подняли реплику PostgreSQL, хотим увести на неё тяжёлые отчёты и вообще всё, что GET. Не понимаю две вещи: как Rails решает, когда читать с реплики, и что будет, если пользователь что-то сохранил и сразу открыл страницу, а реплика отстаёт. Rails 8.1.
В модели две роли:
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
connects_to database: { writing: :primary, reading: :primary_replica }
end
В database.yml у реплики replica: true. Автоматическое переключение генерирует bin/rails g active_record:multi_db, в инициалайзере будет так:
Rails.application.configure do
config.active_record.database_selector = { delay: 2.seconds }
config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
end
GET и HEAD идут на реплику, остальное на основную. После любой записи 2 секунды запросы этого пользователя читают с основной, время записи хранится в сессии. Это ровно ваш случай с «сохранил и открыл».
Включил, задержку поставил 5 секунд: в пиковые часы реплика отстаёт до трёх. Нагрузка на основную по CPU упала примерно с 70 до 45 процентов. Отчёты обернул явно. Гайд, по которому делал, если кому надо: https://guides.rubyonrails.org/active_record_multiple_databases.html