← Назад к вопросам

Что такое асинхронная репликация?

3.0 Senior🔥 141 комментариев
#DevOps и инфраструктура#Базы данных (SQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Асинхронная репликация: концепция и реализация

Асинхронная репликация — это процесс копирования данных с основного (master) сервера базы данных на один или несколько вспомогательных (slave/replica) серверов с задержкой. Основной сервер не ждет подтверждения репликации.

1. Как работает асинхронная репликация

Мастер (Master)                    Слейв (Slave)
┌─────────────────┐                ┌─────────────────┐
│ Клиент пишет    │                │                 │
│ данные          │                │                 │
└────────┬────────┘                └────────┬────────┘
         │                                   │
         ├─ Записывает в Binary Log          │
         │  (WAL - Write Ahead Log)          │
         │                                   │
         ├─ COMMIT возвращается клиенту      │
         │  (он не знает о репликации)       │
         │                                   │
         ├──────────────────────────────────→│
         │   Отправляет изменения асинхронно │
         │                                   │
         │                      ┌────────────┤
         │                      │ Применяет   │
         │                      │ изменения   │
         │                      │ позже       │
         │                      └────────────┘

2. Синхронная vs Асинхронная репликация

Синхронная репликация

Мастер ──запись──→ Слейв
   ↑                ↓
   └────ДА/НЕТ────┘
   Мастер ждет!

Плюсы:

  • Данные гарантированно на всех серверах
  • Нет потери данных при сбое

Минусы:

  • Медленнее (зависит от сетевой задержки)
  • Сбой слейва блокирует мастер

Асинхронная репликация

Мастер ──запись──→ Слейв
   │                ↓
   └─COMMIT──→ Клиент
        (слейв обновляется позже)

Плюсы:

  • Быстрее (не ждём подтверждения)
  • Сбой слейва не влияет на мастер
  • Масштабируемость

Минусы:

  • Возможна потеря данных при сбое мастера
  • Слейв может быть "позади" мастера

3. Процесс репликации в MySQL/PostgreSQL

┌──────────────────────────────────────────────────┐
│ 1. Клиент делает INSERT/UPDATE/DELETE на мастере │
└────────────────┬─────────────────────────────────┘
                 │
┌────────────────▼─────────────────────────────────┐
│ 2. Запись в Binary Log (MySQL) или WAL (PG)      │
│    Содержит все изменения для повтора            │
└────────────────┬─────────────────────────────────┘
                 │
┌────────────────▼─────────────────────────────────┐
│ 3. COMMIT ✓ (клиент получает подтверждение)     │
│    Мастер не ждет слейва!                        │
└────────────────┬─────────────────────────────────┘
                 │
┌────────────────▼─────────────────────────────────┐
│ 4. Binlog Dump Thread отправляет на слейв       │
│    (асинхронно, в фоне)                          │
└────────────────┬─────────────────────────────────┘
                 │
┌────────────────▼─────────────────────────────────┐
│ 5. Слейв получает изменения                      │
│    (может быть задержка в миллисекунды/секунды)  │
└────────────────┬─────────────────────────────────┘
                 │
┌────────────────▼─────────────────────────────────┐
│ 6. Слейв применяет изменения локально            │
│    (Relay Log → SQL Thread → локальные таблицы)  │
└──────────────────────────────────────────────────┘

4. Настройка репликации в MySQL

На мастере:

-- 1. Включаем binary logging
SHOW VARIABLES LIKE 'log_bin';
-- должно быть ON в my.cnf

-- 2. Создаем пользователя для репликации
CREATE USER 'replication'@'slave_ip' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'slave_ip';
FLUSH PRIVILEGES;

-- 3. Получаем текущее положение в логе
FLUSH TABLES WITH READ LOCK;  -- Блокируем писи
SHOW MASTER STATUS;           -- Запоминаем File и Position
UNLOCK TABLES;

-- 4. Снимаем бэкап
mysqldump -u root -p --all-databases --master-data > dump.sql

На слейве:

-- 1. Восстанавливаем данные
mysql -u root -p < dump.sql

-- 2. Настраиваем параметры слейва (в my.cnf)
-- [mysqld]
-- relay-log = mysql-relay-bin
-- relay-log-index = mysql-relay-bin.index
-- server-id = 2

-- 3. Подключаемся к мастеру
CHANGE MASTER TO
    MASTER_HOST = 'master_ip',
    MASTER_USER = 'replication',
    MASTER_PASSWORD = 'password',
    MASTER_LOG_FILE = 'mysql-bin.000001',
    MASTER_LOG_POS = 154;

-- 4. Запускаем слейв
START SLAVE;

-- 5. Проверяем статус
SHOW SLAVE STATUS\G
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes
-- Seconds_Behind_Master: 0

5. PostgreSQL потоковая репликация

# На мастере (postgresql.conf)
wal_level = replica
max_wal_senders = 10
wal_keep_size = 1GB

# На слейве (recovery.conf)
standby_mode = on
primary_conninfo = 'host=master_ip user=postgres'

6. Проблемы асинхронной репликации

Проблема: Потеря данных при крахе мастера

# Мастер
INSERT INTO users VALUES (1, 'Alice');  # Успешно
COMMIT;                                  # Возвращена клиенту
# Но слейв еще не получил это!

# Мастер падает до того как отправить на слейв
# Данные потеряны!

Решение: Включить semi-sync репликацию

-- На мастере (MySQL)
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = ON;
SET GLOBAL rpl_semi_sync_master_timeout = 10000;

-- На слейве
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled = ON;

7. Задержка репликации (Replication Lag)

-- Проверяем задержку на слейве
SHOW SLAVE STATUS;
-- Seconds_Behind_Master показывает задержку

-- Если > 0, значит есть отставание
SELECT TIMESTAMPDIFF(SECOND, ts, NOW()) as lag_seconds
FROM heartbeat_table;

8. Использование репликации в приложении

import MySQLdb
from contextlib import contextmanager

class DatabasePool:
    def __init__(self):
        self.master = MySQLdb.connect(host='master', user='root')
        self.slaves = [
            MySQLdb.connect(host='slave1', user='root'),
            MySQLdb.connect(host='slave2', user='root'),
        ]
    
    @contextmanager
    def get_connection(self, read_only=False):
        if read_only:
            # Используем слейв для чтения
            conn = random.choice(self.slaves)
        else:
            # Используем мастер для записи
            conn = self.master
        
        try:
            yield conn
        finally:
            conn.close()

# Использование
db = DatabasePool()

# Запись на мастер
with db.get_connection(read_only=False) as conn:
    cursor = conn.cursor()
    cursor.execute("INSERT INTO users VALUES (%s, %s)", (1, 'Alice'))
    conn.commit()

# Чтение со слейва
with db.get_connection(read_only=True) as conn:
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users")
    print(cursor.fetchall())

Ключевые выводы:

  • Асинхронная репликация — мастер не ждет подтверждения слейва
  • Быстрее синхронной, но есть риск потери данных
  • Используй для читаемых нагрузок (селекты на слейвах)
  • Master-Slave архитектура — пишем на мастер, читаем со слейва
  • Задержка репликации (lag) — всегда может быть
  • Semi-sync репликация — компромисс между скоростью и надежностью
  • Мониторь репликацию с помощью SHOW SLAVE STATUS
Что такое асинхронная репликация? | PrepBro