Что такое синхронная репликация? Опишите её преимущества и недостатки.

Ответ

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

Пошаговый процесс:

  1. Клиент отправляет запрос на запись лидеру.
  2. Лидер записывает данные локально.
  3. Лидер пересылает данные всем синхронным репликам.
  4. Лидер ожидает подтверждения (acknowledgment) от каждой реплики.
  5. Только после получения всех подтверждений лидер отправляет клиенту ответ об успешном завершении операции.

Концептуальный пример на Go:

Этот код иллюстрирует блокирующую природу синхронной репликации. Функция не завершится, пока все реплики не "прочитают" данные из канала.

// replicas - это слайс небуферизованных каналов
func syncReplicate(data string, replicas []chan string) error {
    // Отправляем данные в каждую реплику.
    // Операция `replica <- data` является блокирующей.
    for _, replica := range replicas {
        replica <- data
    }
    // Функция вернет управление только после того,
    // как все реплики подтвердят получение данных (прочитав из канала).
    return nil
}

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

  • Строгая согласованность (Strong Consistency): После успешной записи клиент гарантированно может прочитать эти данные с любой реплики.
  • Гарантия отсутствия потерь данных (Zero Data Loss): Если лидер выходит из строя после подтверждения записи, данные гарантированно сохранены как минимум на одной реплике.

Недостатки:

  • Высокая задержка записи (High Write Latency): Общая задержка операции определяется скоростью самого медленного узла в синхронной группе.
  • Низкая отказоустойчивость на запись: Если хотя бы одна синхронная реплика выходит из строя, вся система (или, по крайней мере, операции записи) может остановиться до её восстановления.

Примеры использования:

Синхронная репликация используется в системах, где сохранность и консистентность данных имеют наивысший приоритет, например:

  • Финансовые системы и банковские транзакции.
  • Управление критически важными конфигурационными данными.

Ответ 18+ 🔞

А, синхронная репликация! Ну это ж классика, блядь, когда всё должно быть по-взрослому, на совесть. Представь себе, ты пишешь данные, а система тебе такая: «Спокойно, чувак, я не просто так, я щас всем своим подружкам об этом сообщу, и только когда они все кивнут, тогда и тебе отпишусь». Вот это и есть синхронность, ёпта.

Как это работает, если на пальцах:

  1. Ты, такой важный клиент, суёшь свои данные лидеру — главному узлу.
  2. Лидер их у себя записывает, но не расслабляется, сука.
  3. Он тут же начинает рассылать эту историю всем своим синхронным репликам — это как его верные оруженосцы.
  4. И сидит, ждёт, блядь. Ждёт, пока каждая из этих реплик не отзовётся: «Да, босс, принял, записал, всё чётко».
  5. И только когда все ответили, лидер, выдохнув, говорит тебе: «Всё, брат, операция успешна, можешь спать спокойно».

Вот, смотри, как это выглядит в коде на Go, чтоб совсем понятно было:

// replicas - это слайс небуферизованных каналов
func syncReplicate(data string, replicas []chan string) error {
    // Рассылаем данные каждой реплике.
    // Операция `replica <- data` — это ж блокировка, чувак! Пока реплика не прочитает, мы тут зависнем.
    for _, replica := range replicas {
        replica <- data
    }
    // Управление вернётся только тогда, когда ВСЕ реплики подтвердят получение (прочитают из канала).
    return nil
}

Видишь? Функция syncReplicate — это как тот самый лидер. Она не сдвинется с места, пока не убедится, что все «подружки» (реплики) данные получили. Никакого «отправил и забыл», тут всё серьёзно.

Чем это, блядь, хорошо:

  • Железобетонная консистентность: Как только тебе пришло «ок», можешь хоть с первой, хоть с десятой реплики эти данные читать — они там будут. Никаких сюрпризов.
  • Потерь данных — ноль, абсолютный ноль: Если лидер вдруг накроется медным тазом сразу после ответа тебе, то не парься. Данные уже живут как минимум на одной другой машине. Не пропадёт.

А чем это, сука, плохо:

  • Скорость записи — как у раненого слона: Вся операция упрётся в самого тормозного участника. Одна реплика задумалась — и все, пиздец, ждём у моря погоды. Задержки могут быть овердохуищные.
  • Хрупкость, как яичко: Если хоть одна синхронная реплика легла и не отвечает, то всё, приехали. Система записи может просто встать колом, пока эту реплику не починят. Отказоустойчивость на запись — ниже плинтуса.

Где эту штуку применяют? Да там, где по-другому никак, где любая потеря или рассинхрон — это финансовый пиздец или катастрофа:

  • Переводы бабла в банках (представь, деньги списали, но нигде не отразились — волнение ебать).
  • Хранение критически важных конфигов, от которых весь сервис живёт.

Короче, инструмент мощный, но с характером. Как скальпель — в умелых руках спасает жизнь, а если херачить с размаху, то можно и отрезать что-нибудь нужное.