Что такое репликация данных в базах данных и зачем она нужна?

«Что такое репликация данных в базах данных и зачем она нужна?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Репликация данных — это процесс автоматического копирования и поддержания согласованности данных между несколькими экземплярами базы данных (репликами). Основные цели: повышение доступности, отказоустойчивость, масштабирование чтения и географическое распределение.

Основные модели репликации

1. Master-Slave (Primary-Replica)

  • Master (Primary): Единственный узел, принимающий операции записи (INSERT, UPDATE, DELETE).
  • Slave (Replica, Read-Replica): Узлы, которые получают копию данных с мастера и обслуживают только запросы на чтение.

Как работает: Изменения с мастера асинхронно (или синхронно) передаются на реплики через бинарный лог (binlog) или WAL (Write-Ahead Log).

Преимущества:

  • Масштабирование чтения: Нагрузку SELECT можно распределить по многим репликам.
  • Резервирование: При падении мастера одна из реплик может быть повышена до новой первичной.
  • Аналитика: Запросы для отчетов можно выполнять на реплике, не нагружая мастер.

Пример конфигурации чтения/записи в Spring Boot:

@Configuration
public class DatabaseConfig {

    // Бин для MASTER (запись)
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }

    // Бин для SLAVE (чтение)
    @Bean
    @ConfigurationProperties("spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }

    // Динамический маршрутизатор данных
    @Bean
    public DataSource routingDataSource(
            @Qualifier("masterDataSource") DataSource master,
            @Qualifier("slaveDataSource") DataSource slave) {

        AbstractRoutingDataSource router = new AbstractRoutingDataSource() {
            @Override
            protected Object determineCurrentLookupKey() {
                // Ключ определяется контекстом (например, аннотацией @Transactional)
                return TransactionSynchronizationManager.isCurrentTransactionReadOnly() 
                        ? "slave" 
                        : "master";
            }
        };

        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("master", master);
        targetDataSources.put("slave", slave);

        router.setTargetDataSources(targetDataSources);
        router.setDefaultTargetDataSource(master); // По умолчанию мастер
        return router;
    }
}

// Сервис использует маршрутизацию автоматически
@Service
public class UserService {

    @Transactional // Будет использовать master
    public User createUser(User user) {
        return userRepository.save(user); // Запись идет на мастер
    }

    @Transactional(readOnly = true) // Будет использовать slave
    public User getUser(Long id) {
        return userRepository.findById(id).orElse(null); // Чтение идет на реплику
    }
}

2. Master-Master (Multi-Primary)

  • Несколько мастеров, каждый может принимать запись.
  • Изменения реплицируются между всмастерами.
  • Сложность: Высокий риск конфликтов при одновременном изменении одних данных в разных мастерах. Требуются механизмы разрешения конфликтов.
  • Применение: Географическое распределение для уменьшения задержки записи.

3. Шардирование (Сегментирование)

  • Горизонтальное разделение данных: Разные строки одной таблицы хранятся на разных узлах (шардах) по определенному ключу (например, user_id).
  • Решает проблему масштабирования записи.
  • Часто комбинируется с репликацией: каждый шард может иметь свои реплики.

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

  • Синхронная: Мастер ждет подтверждения записи от реплик, прежде чем подтвердить транзакцию клиенту. Гарантирует полную согласованность, но снижает производительность и доступность (при падении реплики мастер может «зависнуть»).
  • Асинхронная: Мастер подтверждает запись клиенту сразу, а репликация происходит «в фоне». Выше производительность и доступность, но возможна временная несогласованность (replica lag).

Итог: Репликация — ключевой механизм для построения надежных, производительных и отказоустойчивых систем хранения данных.