Реплика для чтения ...
 
Уведомления
Очистить всё

Реплика для чтения в Rails 8.1: как он решает, куда идти?

4 Сообщения
3 Пользователи
2 Реакции
300 Просмотры
Давид Г
Сообщения: 7
Автор темы
Разобрался с блоками тимлид
Присоединился: 10 месяцев назад
[#111]

Подняли реплику PostgreSQL, хотим увести на неё тяжёлые отчёты и вообще всё, что GET. Не понимаю две вещи: как Rails решает, когда читать с реплики, и что будет, если пользователь что-то сохранил и сразу открыл страницу, а реплика отстаёт. Rails 8.1.


3 ответа
gosha70
Сообщения: 17
Пишет тесты бэкенд-разработчик, удалёнка
Присоединился: 3 года назад

В модели две роли:

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 секунды запросы этого пользователя читают с основной, время записи хранится в сессии. Это ровно ваш случай с «сохранил и открыл».


Ответ
1 ответ
kostya.sokurov
Присоединился: 4 года назад

Держит прод бэкенд-разработчик, senior
Сообщения: 73

Только задержку подбирайте по реальному отставанию, а не берите по умолчанию. Посмотрите now() - pg_last_xact_replay_timestamp() на реплике в час пик. И для отчётов я бы на автоматику не надеялся, а оборачивал явно, ActiveRecord::Base.connected_to(role: :reading) { ... }, чтобы по коду было видно, куда идёт запрос.


Ответ
Давид Г
Сообщения: 7
Автор темы
Разобрался с блоками тимлид
Присоединился: 10 месяцев назад

Включил, задержку поставил 5 секунд: в пиковые часы реплика отстаёт до трёх. Нагрузка на основную по CPU упала примерно с 70 до 45 процентов. Отчёты обернул явно. Гайд, по которому делал, если кому надо: https://guides.rubyonrails.org/active_record_multiple_databases.html


Ответ