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

Для чего используют Master-Slave?

3.0 Senior🔥 121 комментариев
#Базы данных и SQL

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

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

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

# Master-Slave репликация в базах данных

Master-Slave (или в современной терминологии Primary-Replica) — это паттерн репликации данных, при котором одна БД (Master) выступает источником истины, а другие (Slave) получают копию данных.

Основная архитектура

Master сервер обрабатывает все write операции. Slave серверы получают изменения через репликацию и обслуживают read операции.

Основные цели использования

1. Масштабируемость для чтения (Read Scaling)

Это главная цель Master-Slave. Когда возрастает нагрузка на чтение, распределяем её между несколькими серверами:

public class UserRepository {
  private DataSource masterDataSource;  // для WRITE
  private DataSource[] slaveDataSources; // для READ
  
  public User findById(UUID id) {
    // Читаем с одного из slave серверов (round-robin)
    DataSource slave = roundRobinSelect(slaveDataSources);
    return queryWithConnection(slave, 
      "SELECT * FROM users WHERE id = ?", id);
  }
  
  public void save(User user) {
    // Пишем только в master
    return queryWithConnection(masterDataSource,
      "INSERT INTO users ...");
  }
}

Пример: Master обрабатывает 1000 write ops/sec, каждый Slave — 5000 read ops/sec. С тремя Slave можем обслужить 15,000 read ops/sec.

2. Высокая доступность (High Availability)

Если Master выходит из строя, один из Slave может быть пропагандирован в Master:

class HighAvailabilityDataSource {
  private PrimaryDatabase master;
  private List<ReplicaDatabase> slaves;
  
  public synchronized void onMasterFailure() {
    // Выбираем самый актуальный slave
    ReplicaDatabase newMaster = slaves.stream()
      .max(comparing(ReplicaDatabase::getReplicationLag))
      .orElseThrow();
    
    // Пропагандируем его в master
    newMaster.promoteToPrimary();
    
    // Обновляем конфиг
    master = newMaster;
    
    // Переприсоединяем других slaves к новому master
    slaves.forEach(slave -> slave.setMaster(newMaster));
  }
}

3. Data Backup и Archive

Slave можно использовать как резервную копию без потери основной БД. На slave можно делать backup без блокировки master, пока тот обслуживает пользователей.

4. Аналитика и Reporting

Если запускать heavy аналитические запросы на Master, они замедлят основное приложение. Используем Slave для этого:

public class UserService {
  private DataSource masterDs;     // для OLTP
  private DataSource analyticsDs;  // для OLAP
  
  public User findById(UUID id) {
    return query(masterDs, "SELECT * FROM users WHERE id = ?");
  }
  
  // Тяжёлые аналитические запросы на отдельном сервере
  public List<UserStatistics> generateMonthlyReport() {
    return query(analyticsDs,
      "SELECT user_id, COUNT(*) as actions_count " +
      "FROM user_actions WHERE date >= now() - interval 1 month " +
      "GROUP BY user_id");
  }
}

5. Test и Development

Можно использовать copy данных с Slave для тестирования без затрагивания production.

Как работает репликация

Master логирует все write операции в binary log. Slave подписывается на этот лог, получает команды и выполняет их локально.

Есть два подхода:

  1. Statement-based: логируют SQL команды. Проблема если есть NOW(), UUID() — результаты могут различаться.
  2. Row-based: логируют изменения по строкам. Современный подход, более надёжный.

Проблемы и решения

Replication Lag (задержка репликации)

Данные на Slave могут отставать на несколько секунд. Если сразу после INSERT читать с lag-ging Slave, можем не найти данные:

// Решение: Read From Master After Write
public void createAndGet(Comment comment) {
  master.save(comment);      // Пишем в master
  return master.findById(comment.getId()); // Читаем из master
}

Write-Write Conflicts в Multi-Master

Если несколько Master серверов пишут одновременно — возникают конфликты. Поэтому используется один Master (классическая архитектура).

Когда использовать Master-Slave

  1. Нужно масштабировать read операции
  2. Требуется высокая доступность
  3. Нужна резервная копия без блокировки
  4. Есть heavy аналитические запросы

Альтернативы и расширения

  • Шардирование: для масштабирования write операций
  • Гибридный подход: Master-Slave + Sharding
  • Read replicas в облаке: AWS RDS, Google Cloud SQL

Это проверенная временем паттерн, используемая в производстве везде.