
Что такое Репликация?
Репликация — это процесс копирования данных из одной базы данных в другую. Репликация может быть полезна для увеличения доступности и масштабируемости приложений, а также для обеспечения более высокой отказоустойчивости.
Существует два основных подхода при работе с репликацией данных: Master-Slave и Master-Master.
Master-Slave репликация
В этом подходе выделяется один основной сервер базы данных, который называется мастером. На нем происходят все изменения в данных (любые запросы INSERT/UPDATE/DELETE). Slave-сервер постоянно копирует все изменения с master. С приложения на slave-сервер отправляются запросы чтения данных (запросы SELECT).
Таким образом, master-сервер отвечает за изменения данных, а slave — за чтение.
Несколько Слейвов
Преимущество этого типа репликации в том, что вы можете использовать более одного slave. Обычно следует использовать не более 20 slave-серверов при работе с одним мастером.
Например, создание нескольких дополнительных slave-серверов позволяет снять с основного сервера нагрузку и повысить общую производительность системы, а также можно организовать слэйвы под конкретные ресурсоёмкие задачи и таким образом, например, упростить составление серьёзных аналитических отчётов — используемый для этих целей slave может быть нагружен на 100%, но на работу других пользователей приложения это не повлияет.
Задержка репликации
Асинхронность репликации означает, что данные на slave могут появиться с небольшой задержкой. Поэтому в последовательных операциях необходимо использовать чтение с master, чтобы получить актуальные данные.
Типы репликации
- Streaming Replication — это наиболее распространенный тип репликации в PostgreSQL. Он основан на механизме записи журнала транзакций (WAL) и позволяет копировать данные в режиме реального времени с одного сервера на другой. В этом случае один сервер является мастером (primary), а другой — репликой (standby). Реплика получает данные от мастера и применяет их к своей копии базы данных. Если мастер выходит из строя, реплика может быть продвинута до мастера.
- Logical Replication — это новый тип репликации, введенный в PostgreSQL 10. Он позволяет копировать данные на уровне таблицы или даже на уровне отдельных строк. Это может быть полезно для репликации только определенных таблиц или для репликации данных между базами данных с разными схемами.
- Slony-I — это стороннее расширение для PostgreSQL, которое предоставляет механизм репликации на основе триггеров. Он позволяет копировать данные между несколькими серверами PostgreSQL и обеспечивает высокую отказоустойчивость и масштабируемость.
- Bucardo — это еще одно стороннее расширение для PostgreSQL, которое предоставляет механизм репликации на основе триггеров. Он позволяет копировать данные между несколькими серверами PostgreSQL и обеспечивает высокую отказоустойчивость и масштабируемость.
Пример работы в Rails 6
Для начала в database.yml добавьте данные primary и primary_replica.
default: &default
host: <%= ENV['DATABASE_HOST'] %>
port: 5432
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
database: <%= ENV['DATABASE_NAME'] %>
username: <%= ENV['DATABASE_USER'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
production:
primary:
<<: *default
primary_replica:
<<: *default
host: <%= ENV['DATABASE_HOST_REPLICA'] %>
replica: true
В application_record.rb добавьте (у меня только для окружения production):
connects_to database: { writing: :primary, reading: :primary_replica } if Rails.env.production?
Настроим активацию автоматического переключения соединения в production.rb:
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
Наконец, чтобы использовать реплику только для чтения, необходимо подключить middleware для автоматического переключения соединений.
Автоматическое переключение позволяет приложению переключаться между мастером и репликой в зависимости от HTTP-метода и того, была ли недавняя запись.
Если приложение получает запрос POST, PUT, DELETE или PATCH, оно автоматически выполнит запись в основную базу данных. В течение указанного времени после записи приложение будет читать с мастера. Для запросов GET или HEAD — читать из реплики, если не было недавней записи.