Налаштування реплікації бази даних Master-Slave для веб-застосунку

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Налаштування реплікації бази даних Master-Slave для веб-застосунку
Складна
~3-5 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Настройка репліцирування Master-Slave для веб-додатків

Реплікація вирішує дві задачі: відказостійкість (failover) та масштабування читання. Розглядаємо PostgreSQL streaming replication — стандартний та надійний підхід.

Архітектура

App сервери
    │
    ├── запис ──▶ Primary (master)
    │                    │
    │              WAL stream
    │                    │
    └── читання ──▶ Replica 1 (hot standby)
                   Replica 2 (hot standby)

Hot standby — реплика приймає SELECT-запити. Cold standby — тільки для failover, без читання.

Настройка Primary

postgresql.conf на основному сервері:

# Replication
wal_level = replica          # мінімум для streaming replication
max_wal_senders = 5          # максимум одночасних репліцірунків з'єднань
wal_keep_size = 1GB          # скільки WAL тримати на диску для відстаючої реплік
max_replication_slots = 5    # фізичні слоти реплікації

# Performance
synchronous_commit = on      # on = синхронний запис WAL, off = швидше, ризик втратити 1 транзакцію

pg_hba.conf на primary — дозволяємо підключення репліцірунка:

# TYPE  DATABASE        USER            ADDRESS                 METHOD
host    replication     replicator      10.0.1.0/24             scram-sha-256

Створюємо користувача для реплікації:

CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'strong_password';

Настройка Replica (PostgreSQL 12+)

На реплікі запускаємо pg_basebackup для початкової синхронізації:

# На сервері реплік, PostgreSQL зупинений
pg_basebackup \
    -h 10.0.1.10 \         # IP primary
    -U replicator \
    -D /var/lib/postgresql/14/main \
    -P \                   # прогрес
    -Xs \                  # включити WAL stream
    -R                     # створити standby.signal та записати primary_conninfo

Прапор -R створює standby.signal та додає в postgresql.auto.conf:

primary_conninfo = 'host=10.0.1.10 port=5432 user=replicator password=strong_password application_name=replica1'
primary_slot_name = 'replica1_slot'

postgresql.conf на реплікі:

hot_standby = on              # приймати SELECT на реплікі
hot_standby_feedback = on     # реплік повідомляє primary про свої транзакції (запобігає vacuum race)
max_standby_streaming_delay = 30s

Слоти реплікації

Слот гарантує, що primary не видалить WAL-сегменти, поки реплік їх не отримає:

-- На primary
SELECT pg_create_physical_replication_slot('replica1_slot');

-- Перевірка статусу
SELECT slot_name, active, restart_lsn, confirmed_flush_lsn,
       pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) AS lag_bytes
FROM pg_replication_slots;

Небезпека слотів: якщо реплік надовго відключиться — primary буде накопичувати WAL-файли. Контролюємо:

# postgresql.conf на primary
max_slot_wal_keep_size = 10GB   # PostgreSQL 13+: максимум WAL для слота

Моніторинг репліцірунків лага

-- На primary: статус усіх реплік
SELECT
    application_name,
    client_addr,
    state,
    sent_lsn,
    write_lsn,
    flush_lsn,
    replay_lsn,
    pg_size_pretty(pg_wal_lsn_diff(sent_lsn, replay_lsn)) AS replay_lag_bytes,
    write_lag,
    flush_lag,
    replay_lag
FROM pg_stat_replication;

-- На реплікі: поточний лаг
SELECT
    now() - pg_last_xact_replay_timestamp() AS replication_lag_seconds,
    pg_is_in_recovery() AS is_replica;

Настройка додатку

На рівні додатку маршрутизуємо запити: запис → primary, читання → replica.

Для Node.js + Sequelize:

const sequelize = new Sequelize({
  dialect: 'postgres',
  replication: {
    read: [
      { host: '10.0.1.11', username: 'app', password: process.env.DB_PASS, database: 'mydb' },
      { host: '10.0.1.12', username: 'app', password: process.env.DB_PASS, database: 'mydb' },
    ],
    write: {
      host: '10.0.1.10', username: 'app', password: process.env.DB_PASS, database: 'mydb',
    },
  },
  pool: { max: 10, idle: 10000 },
});

Для Python (SQLAlchemy) — через custom routing або бібліотеку sqlalchemy-rwconn.

PgBouncer як прокси

Рекомендується ставити PgBouncer перед кожним сервером БД:

App → PgBouncer (primary:6432) → PostgreSQL Primary :5432
App → PgBouncer (replica:6432) → PostgreSQL Replica :5432

PgBouncer зменшує кількість реальних з'єднань до PostgreSQL — важливо при сотнях воркерів додатку.

Автоматичний failover

Patroni — стандарт для автоматичного failover PostgreSQL в production:

# /etc/patroni/config.yml (фрагмент)
scope: postgres-cluster
name: node1

restapi:
  listen: 0.0.0.0:8008
  connect_address: 10.0.1.10:8008

etcd:
  hosts: 10.0.1.20:2379,10.0.1.21:2379,10.0.1.22:2379

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576   # 1MB
  pg_hba:
    - host replication replicator 10.0.1.0/24 scram-sha-256

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 10.0.1.10:5432
  data_dir: /var/lib/postgresql/14/main
  parameters:
    max_connections: 200
    wal_level: replica
    max_wal_senders: 5

Patroni використовує etcd (або Consul, ZooKeeper) як distributed lock. При отказі primary — автоматично промоутує реплік з найменшим лагом.

Графіки

Ручна настройка streaming replication (primary + 1–2 реплік, без failover): 1 день. Установка та настройка Patroni з etcd та HAProxy для автоматичного failover: 2–3 дні.