сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Распределённые системы

Распределённые системы: репликация и отказы

Репликация и отказы

Репликация даёт переживаемость отказов, чтение с реплик и гео-близость, и порождает все вопросы про лаг и конфликты. Собес проверяет, понимаешь ли ты цену асинхронной репликации и ужасы фейловера.

Стержень: асинхронная репликация это окно потери данных при смерти лидера, а фейловер без fencing - прямой путь к split brain.

// Формулировки: «синхронная или асинхронная репликация?», «что такое split brain?», «почему нельзя читать баланс с реплики?».

Single-leader и failover

Single-leader: запись идёт через лидера, реплики догоняют. Асинхронная репликация означает окно потери (RPO > 0) при смерти лидера - последние подтверждённые транзакции могли не доехать. Синхронная убирает потерю ценой латентности и зависимости от живости реплики; полусинхрон - компромисс.

Failover полон ловушек: ложное срабатывание (лидер жив, моргнула сеть), split brain (два лидера принимают записи), потеря невоспроизведённых транзакций.

// Поэтому автофейловер без осознания RPO (recovery point objective) рождает вопрос «куда делись последние транзакции?». Уровень допустимой потери проговаривают заранее, а не после аварии.

replication lag
отставание реплики от лидера
RPO / RTO
допустимая потеря данных / допустимое время восстановления

Fencing и конфликты записи

Fencing - гарантированное отрезание старого лидера при фейловере (token или STONITH). Без него старый лидер, «ожив» после паузы, продолжит принимать записи, и два узла запишут в одни данные - split brain, который потом не склеить.

Multi-leader и leaderless (Dynamo-стиль) пишут в несколько мест, поэтому требуют конфликт-резолюшн: LWW (last write wins) - «побеждает последняя запись» - теряет данные молча, версии-векторы отслеживают причинность, CRDT (conflict-free replicated data type) сходятся математически.

// LWW особенно коварен: он разрешает конфликт по часам машин, а рассинхрон часов между узлами молча выбрасывает «проигравшие» записи. Часы в распределёнке - ненадёжный арбитр.

split brain
два узла считают себя лидером одновременно
fencing
гарантированное отрезание старого лидера (token/STONITH)

Лаг и природа отказов

Лаг репликации - продуктовая реальность: реплика отстаёт на секунды-минуты. Пользователь, читающий свои только что записанные данные с отстающей реплики, видит «откат» - отсюда саппорт-тикеты «деньги исчезли». Критичные чтения маршрутизируют на лидера.

Отказы сети не бинарны: бывают медленные линки, частичная и асимметричная связность. Таймаут не отличает мёртвого узла от медленного, поэтому в распределёнке полагаются на кворумы и фенсинг, а не на «пингнул и решил».

// Гео-репликация между регионами почти всегда асинхронна - скорость света не обойти. RPO и RTO (recovery time objective) для гео проговаривают с бизнесом заранее.

asymmetric partition
связь есть в одну сторону, нет в другую
стейл-чтение
чтение с отстающей реплики отдаёт прошлое

Как отвечать: «Что такое split brain и как его предотвращают?»

Split brain это когда в кластере одновременно оказываются два лидера, оба принимают записи в одни и те же данные, и история расходится так, что потом её не склеить. Возникает при фейловере: система решила, что старый лидер умер, и назначила нового, а старый на самом деле жив - просто моргнула сеть или он завис и очнулся. Теперь пишут двое. Предотвращают это фенсингом - гарантированным отрезанием старого лидера. Практически это fencing token: монотонный номер, который растёт при каждой смене лидера; хранилище принимает запись только с актуальным токеном и отвергает записи со старым, так что ожившый прежний лидер уже ничего не запишет. Более грубый вариант - STONITH, физически вырубить старый узел. И основа всего - назначать лидера через кворумное большинство, чтобы две половины кластера не выбрали двух лидеров.

Почему это сильный ответ: точное определение, механизм возникновения (ложная смерть лидера), и конкретная защита через fencing token с объяснением, как именно токен отсекает старого лидера.

На чём валят

  • Асинхронная репликация плюс автофейловер без осознания RPO - «куда делись последние транзакции?».
  • Фейловер без fencing - split brain и расхождение данных, которое не склеить.
  • LWW-резолюшн по часам машин - рассинхрон часов молча выбрасывает записи.
  • Читать баланс с отстающей реплики - саппорт-тикеты «деньги исчезли».
  • Тестировать только полную смерть узла - реальность это медленный узел и мигающая сеть.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.

  1. #replication_faults1 / 5
    Что такое replication lag и к чему он приводит при чтении с реплики?
    A)Отставание реплики от лидера: чтение с неё может вернуть устаревшие данные
    B)Общая задержка между нажатием пользователем кнопки в интерфейсе и получением видимого отклика
    C)Полная потеря связи между лидером и репликами без возможности восстановления
    D)Ускорение реплики, из-за которого она по данным опережает своего лидера
    показать ответ и разбор
    +A)Отставание реплики от лидера: чтение с неё может вернуть устаревшие данные

    // разбор: Replication lag — время, на которое follower отстаёт от лидера при асинхронной репликации. Чтение с отстающей реплики возвращает устаревшее значение: классический эффект «оставил комментарий, обновил страницу — его нет». Лечат чтением критичных данных с лидера, read-your-writes-гарантией или мониторингом и ограничением лага.

  2. #replication_faults2 / 5
    Что задаёт кворумное условие W + R > N в распределённом хранилище?
    A)Максимально допустимое число узлов, которым разрешено работать в кластере
    B)Пересечение множеств записи и чтения гарантирует, что чтение застанет свежую запись
    C)Скорость сети, необходимую для синхронизации реплик между собой
    D)Требование блокировать чтения на период, пока в системе идёт хотя бы одна незавершённая операция записи в реплики
    показать ответ и разбор
    +B)Пересечение множеств записи и чтения гарантирует, что чтение застанет свежую запись

    // разбор: N — число реплик, W — сколько должны подтвердить запись, R — сколько опрашиваются при чтении. Условие W + R > N заставляет множества записи и чтения пересечься хотя бы в одной реплике, а значит, чтение застанет самую свежую запись. Меньшие W и R дают выше доступность и ниже латентность, но рискуют устаревшими чтениями — это настраиваемый компромисс CAP.

  3. #replication_faults3 / 5
    Почему в распределённой системе повторы (retries) требуют идемпотентности операций?
    A)Повторные попытки операций в распределённых системах почти не встречаются на практике
    B)Идемпотентность нужна лишь для ускорения ответа системы, а не для корректности данных
    C)Таймаут ≠ неуспех: операция могла пройти, и повтор без идемпотентности задвоит эффект
    D)Ретраи безопасны, потому что сеть внутри кластера надёжна
    показать ответ и разбор
    +C)Таймаут ≠ неуспех: операция могла пройти, и повтор без идемпотентности задвоит эффект

    // разбор: В сети таймаут не означает, что операция не выполнилась: запрос мог дойти и примениться, а потеряться ответ. Тогда слепой повтор применит действие дважды — двойное списание, дубль заказа. Поэтому создающие операции делают идемпотентными: ключ идемпотентности или дедуп позволяют серверу распознать повтор и не выполнить его снова.

  4. #replication_faults4 / 5
    Что такое replication lag и чем он опасен при чтении с реплики?
    A)Replication lag — время, за которое реплика заменяет упавшего лидера при сбое
    B)Отставание реплики от лидера по времени; чтение с неё может вернуть устаревшие данные (stale read)
    C)Lag означает, что реплика опережает лидера и содержит более свежие данные, чем он сам
    D)Replication lag влияет на скорость записи в лидера, а чтения с реплик остаются актуальны
    показать ответ и разбор
    +B)Отставание реплики от лидера по времени; чтение с неё может вернуть устаревшие данные (stale read)

    // разбор: В асинхронной репликации фолловер применяет изменения лидера с задержкой — replication lag. Чтение с отставшей реплики (обычная практика для разгрузки лидера) может вернуть устаревшее значение: пользователь обновил данные, но реплика ещё не догнала. Отсюда нарушения read-your-writes и монотонности. Лечат: критичные чтения — с лидера, закрепление сессии, кворумные чтения, отслеживание версии/позиции. Лаг — ключевая метрика; всплеск лага при пиковой записи роняет свежесть чтений.

  5. #replication_faults5 / 5
    Что означает кворумное условие W + R > N в реплицированном хранилище?
    A)Что данные копируются на N реплик синхронно перед подтверждением записи
    B)Что для доступности должно работать больше половины N реплик кластера
    C)Записываем в W реплик, читаем из R, и при W+R>N множества пересекаются — чтение застаёт хотя бы одну свежую копию
    D)Что чем больше сумма W+R, тем быстрее выполняются и запись, и чтение одновременно
    показать ответ и разбор
    +C)Записываем в W реплик, читаем из R, и при W+R>N множества пересекаются — чтение застаёт хотя бы одну свежую копию

    // разбор: N — число реплик, W — сколько подтверждают запись, R — сколько опрашивают при чтении. При W+R>N любой кворум чтения гарантированно пересекается с кворумом последней записи хотя бы на одной реплике, поэтому читатель увидит свежее значение (по версии выбирает новейшее). Это настраиваемая согласованность (Dynamo-стиль): W=N,R=1 — быстрые чтения, медленная запись; W=1,R=N — наоборот; W+R>N — баланс. При W+R≤N чтение может целиком попасть на устаревшие реплики.

дальше

Теорию прочитали. Навык ставится повторением

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