Распределённые системы

Репликация данных

Цели урока

  • Объяснять разницу между репликацией и backup и почему одно не заменяет другое
  • Сравнивать Leader-Follower, Multi-Leader и Leaderless по latency, consistency и сложности
  • Рассчитывать кворумные конфигурации N/W/R для заданных требований
  • Выбирать стратегию разрешения конфликтов для конкретного use case

Предварительные знания

  • CAP-теорема: понимание trade-off между consistency и availability
  • Базовое понимание сетевых задержек и partition tolerance
  • Знакомство с транзакциями и ACID-гарантиями

GitLab потерял 300 ГБ production-данных за 5 минут. Backup существовал, но не восстанавливался - никто не проверял. Репликация - не magic bullet, а целая дисциплина с trade-off на каждом шагу.

  • **PostgreSQL streaming replication** - стандарт для highload: primary + 2 hot standby, failover за секунды через Patroni или repmgr
  • **Amazon DynamoDB** - leaderless с tunable consistency: по умолчанию eventual, за дополнительные 2x latency - strongly consistent reads
  • **Cassandra в Netflix** - RF=3 с LOCAL_QUORUM: пережили целый AWS region outage без downtime благодаря multi-DC replication
  • **Google Spanner** - синхронная репликация через Paxos с TrueTime API: strong consistency глобально ценой 7-14 мс commit wait
  • **MySQL semi-sync в Facebook** - при падении лидера гарантировано не более одной потерянной транзакции (одна реплика всегда подтвердила)

Amazon Dynamo и рождение NoSQL

В 2007 Amazon опубликовал Dynamo paper - систему которая управляла корзиной покупок на пике нагрузки в Black Friday. Ключевое решение: отказаться от single leader ради availability. Конфликты разрешает сам клиент (application-level). Эта статья запустила волну NoSQL баз: Cassandra (Facebook, 2008), Riak, Voldemort. Идеи кворумов и consistent hashing из Dynamo используются в каждой современной distributed БД.

Зачем хранить одно в трёх местах

**GitLab, 31 января 2017. 23:23 UTC. Инженер удалил 300 гигабайт production-базы - ошибочный rsync в не ту сторону. Backup-скрипты не работали уже 6 месяцев - никто не проверял. В итоге потеряно 5 000 проектов и 6 часов downtime.** Причина не в ненадёжном железе - причина в единственной копии данных.

**Репликация** - хранение идентичных копий данных на нескольких независимых узлах. Три цели: отказоустойчивость (узел упал - данные живы), низкая задержка (читай с ближайшего узла), масштабирование чтения (10 реплик = 10x read throughput).

СистемаРепликЧто получают
Amazon S33+ в одном регионе, 3+ регионов11 nines durability - потеря файла вероятнее выигрыша в лотерею
PostgreSQL streaming1 primary + N standbyFailover за секунды, read scaling через hot standby
CassandraRF=3 по умолчаниюПережить падение целого дата-центра без потери данных
Kafkareplication.factor=3Потребитель продолжает читать при отказе брокера

Главная сложность репликации - не хранение копий, а **синхронизация изменений**. Клиент записал на Leader в DC West. Как и когда это оказывается на Follower в DC East? Выбор стратегии определяет всё: latency, consistency, что происходит при сетевом разрыве.

Репликация = backup. Есть 3 реплики - данные в безопасности

Репликация и backup - разные вещи. Реплики хранят текущее состояние и тоже получат DELETE или коррупцию. Backup - отдельная копия в point-in-time.

Если выполнить DROP TABLE, все 3 реплики применят эту операцию через секунды. Репликация защищает от отказа железа, но не от ошибки оператора или бага в коде. Для защиты от обоих нужны и реплики, и point-in-time backup в отдельном хранилище.

GitLab потерял production-данные несмотря на то, что backup-скрипты были настроены. Какой принцип репликации был нарушен?

Leader-Follower: один пишет, все читают

**Самая распространённая модель:** один узел (Leader, Primary, Master) принимает все записи. Остальные (Followers, Replicas, Standby) получают изменения через replication log и отвечают на запросы чтения. PostgreSQL, MySQL, MongoDB replica set, Redis Sentinel - все работают по этой схеме.

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

РежимLatency записиГарантияПотеря при failoverПример
СинхроннаяВысокая (+roundtrip до реплики)Strong: follower подтвердил до ACK клиенту0 транзакцийPostgreSQL synchronous_commit=on
АсинхроннаяНизкая (локальный commit)Eventual: реплика отстаёт на N операцийДо нескольких секунд данныхMySQL async, Redis AOF async
ПолусинхроннаяСредняя1 реплика подтвердила до ACKМинимальнаяMySQL semi-sync, PostgreSQL remote_apply

**Replication lag** - фундаментальная проблема асинхронной репликации. Клиент записал на leader, сразу читает с follower - видит старое значение. Решения: sticky sessions (читай с той же реплики что писал), read-your-writes consistency (читай с leader свои последние записи), мониторинг lag через `pg_stat_replication.write_lag`.

PostgreSQL настроен с асинхронной репликацией. Leader принял транзакцию и упал через 200 мс. Что произойдёт с данными?

Multi-Leader и конфликты: когда один лидер - узкое место

**Проблема single leader:** все записи идут через один узел. Если дата-центры в Токио, Дублине и Вирджинии - пользователь из Токио ждёт roundtrip до Вирджинии на каждую запись (170+ мс). Multi-Leader решает это: каждый DC имеет свой leader, клиент пишет в ближайший.

Конфликты: неизбежная цена Multi-Leader

Классический write conflict

DC West: user.name = "Alice" (timestamp 10:00:00.100). DC East: user.name = "Bob" (timestamp 10:00:00.150). Оба DC применили запись локально. Когда реплики синхронизируются - у кого данные правильные? Timestamp не помогает: часы разных серверов расходятся на десятки миллисекунд.

Стратегия разрешенияМеханизмКогда применять
Last Write Wins (LWW)Побеждает запись с наибольшим timestampCassandra по умолчанию. Простота ценой возможной потери данных
First Write WinsПервая запись побеждает, повторные отклоняютсяРегистрация уникального username - важна первая
Merge / CRDTЗначения объединяются по правилам типа данныхСчётчики, наборы (sets), документы в Google Docs
Custom application logicКонфликт передаётся в бизнес-логикуShopping cart (Amazon Dynamo), документы с историей

**Практика:** Multi-Leader редко используется внутри одного DC - там single leader быстрее и проще. Основное применение - geographic distribution (несколько регионов), offline clients (Google Docs, CouchDB - каждый клиент является лидером пока offline), collaborative editing.

Multi-Leader = лучше чем Single Leader - больше лидеров, больше пропускная способность

Multi-Leader добавляет сложность конфликтов. Подходит только для geographic distribution или offline clients.

В рамках одного дата-центра Single Leader проще и даёт предсказуемую consistency. Multi-Leader нужен когда latency до единственного leader неприемлема (>50 мс межрегиональный roundtrip) или когда система должна работать offline.

Google Docs позволяет двум пользователям редактировать один документ одновременно без блокировок. Какой подход к конфликтам используется?

Leaderless и кворумы: Amazon Dynamo против традиций

**Amazon, 2007. Werner Vogels публикует Dynamo paper.** Ни одного лидера - клиент пишет одновременно на N узлов и ждёт подтверждения от W из них. При чтении опрашивает R узлов и берёт самое свежее значение. Если W+R>N - гарантировано пересечение: хотя бы один из R узлов видел последнюю запись. На этой идее построены Cassandra, Riak, DynamoDB.

УзелДействиеРезультат
Node 1Получает запрос на записьACK
Node 2Получает запрос на записьACK
Node 3НедоступенЗапись не дошла
ИтогКворум W=2 достигнут (2 из 3 ACK)Запись успешна

**Кворумное уравнение:** N = число реплик, W = кворум записи, R = кворум чтения. Гарантия: при W + R > N хотя бы один узел из R видел последнюю запись. Типичные конфигурации: N=3, W=2, R=2 (баланс); N=3, W=3, R=1 (максимальная durability записи); N=3, W=1, R=3 (максимальная скорость записи).

МодельСильные стороныСлабые стороныПримеры
Leader-FollowerПростота, strong consistency, ordering гарантированSingle point of bottleneck, failover требует electionPostgreSQL, MySQL, MongoDB RS
Multi-LeaderLow latency в разных регионах, offline workКонфликты неизбежны, сложная consistencyCouchDB, Google Docs (OT), Cassandra multi-DC
LeaderlessВысокая доступность, нет SPOF, tunable consistencyEventual consistency, read repair overhead, версионированиеCassandra, Riak, DynamoDB

W+R>N гарантирует strong consistency как у одного сервера

W+R>N гарантирует только что хотя бы один из прочитанных узлов видел последнюю запись - но выбор правильного значения требует версионирования.

Если два узла вернули разные версии, нужен механизм определить которая свежее: vector clocks, timestamps (ненадёжны без синхронизации часов), или CRDT-семантика. Без этого W+R>N не спасёт от чтения устаревших данных.

Cassandra настроена N=5, W=3, R=3. Сколько узлов может упасть без потери возможности читать данные?

Вопросы для размышления

  • При проектировании системы хранения сессий пользователей (миллион активных, 5 минут TTL) какую модель репликации и кворумную конфигурацию выбрать и почему? Что важнее - не потерять сессию или не задержать ответ?

Связанные уроки

  • ds-02-cap-theorem — CAP-теорема ограничивает гарантии репликации
  • ds-03-consensus — Консенсус необходим для безопасной синхронной репликации
  • ds-04-clocks — Логические часы определяют как измерять replication lag
  • dist-07-2pc — 2PC - один из способов сделать репликацию атомарной
  • dist-09-raft — Raft реализует репликацию журнала через консенсус
  • db-13-transactions
Репликация данных

0

1

Войти