Распределённые системы: репликация и отказы
Репликация даёт переживаемость отказов, чтение с реплик и гео-близость, и порождает все вопросы про лаг и конфликты. Собес проверяет, понимаешь ли ты цену асинхронной репликации и ужасы фейловера.
Стержень: асинхронная репликация это окно потери данных при смерти лидера, а фейловер без 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, остальные разбираются в тренажёре.
- Что такое replication lag и к чему он приводит при чтении с реплики?A)Отставание реплики от лидера: чтение с неё может вернуть устаревшие данныеB)Общая задержка между нажатием пользователем кнопки в интерфейсе и получением видимого откликаC)Полная потеря связи между лидером и репликами без возможности восстановленияD)Ускорение реплики, из-за которого она по данным опережает своего лидера
показать ответ и разбор
+A)Отставание реплики от лидера: чтение с неё может вернуть устаревшие данные// разбор: Replication lag — время, на которое follower отстаёт от лидера при асинхронной репликации. Чтение с отстающей реплики возвращает устаревшее значение: классический эффект «оставил комментарий, обновил страницу — его нет». Лечат чтением критичных данных с лидера, read-your-writes-гарантией или мониторингом и ограничением лага.
- Что задаёт кворумное условие W + R > N в распределённом хранилище?A)Максимально допустимое число узлов, которым разрешено работать в кластереB)Пересечение множеств записи и чтения гарантирует, что чтение застанет свежую записьC)Скорость сети, необходимую для синхронизации реплик между собойD)Требование блокировать чтения на период, пока в системе идёт хотя бы одна незавершённая операция записи в реплики
показать ответ и разбор
+B)Пересечение множеств записи и чтения гарантирует, что чтение застанет свежую запись// разбор: N — число реплик, W — сколько должны подтвердить запись, R — сколько опрашиваются при чтении. Условие W + R > N заставляет множества записи и чтения пересечься хотя бы в одной реплике, а значит, чтение застанет самую свежую запись. Меньшие W и R дают выше доступность и ниже латентность, но рискуют устаревшими чтениями — это настраиваемый компромисс CAP.
- Почему в распределённой системе повторы (retries) требуют идемпотентности операций?A)Повторные попытки операций в распределённых системах почти не встречаются на практикеB)Идемпотентность нужна лишь для ускорения ответа системы, а не для корректности данныхC)Таймаут ≠ неуспех: операция могла пройти, и повтор без идемпотентности задвоит эффектD)Ретраи безопасны, потому что сеть внутри кластера надёжна
показать ответ и разбор
+C)Таймаут ≠ неуспех: операция могла пройти, и повтор без идемпотентности задвоит эффект// разбор: В сети таймаут не означает, что операция не выполнилась: запрос мог дойти и примениться, а потеряться ответ. Тогда слепой повтор применит действие дважды — двойное списание, дубль заказа. Поэтому создающие операции делают идемпотентными: ключ идемпотентности или дедуп позволяют серверу распознать повтор и не выполнить его снова.
- Что такое replication lag и чем он опасен при чтении с реплики?A)Replication lag — время, за которое реплика заменяет упавшего лидера при сбоеB)Отставание реплики от лидера по времени; чтение с неё может вернуть устаревшие данные (stale read)C)Lag означает, что реплика опережает лидера и содержит более свежие данные, чем он самD)Replication lag влияет на скорость записи в лидера, а чтения с реплик остаются актуальны
показать ответ и разбор
+B)Отставание реплики от лидера по времени; чтение с неё может вернуть устаревшие данные (stale read)// разбор: В асинхронной репликации фолловер применяет изменения лидера с задержкой — replication lag. Чтение с отставшей реплики (обычная практика для разгрузки лидера) может вернуть устаревшее значение: пользователь обновил данные, но реплика ещё не догнала. Отсюда нарушения read-your-writes и монотонности. Лечат: критичные чтения — с лидера, закрепление сессии, кворумные чтения, отслеживание версии/позиции. Лаг — ключевая метрика; всплеск лага при пиковой записи роняет свежесть чтений.
- Что означает кворумное условие 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 чтение может целиком попасть на устаревшие реплики.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.