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

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

Цели урока

  • Объяснить три причины репликации и когда каждая актуальна
  • Описать Leader-Follower модель и trade-off синхронной vs асинхронной репликации
  • Понять проблему конфликтов в Multi-Leader и основные стратегии разрешения
  • Рассчитать кворумы W/R/N для Leaderless системы под заданные требования

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

  • Понимание CAP-теоремы и eventual consistency
  • Базовые знания о транзакциях и WAL (Write-Ahead Log)
  • Знакомство с концепцией distributed failure modes

GitHub, октябрь 2018: 24 секунды сетевого сбоя рассинхронизировали MySQL-реплики и привели к 5 часам деградации. Выбор модели репликации - это выбор между скоростью, консистентностью и сложностью конфликтов.

  • **PostgreSQL streaming replication** - Leader-Follower с synchronous_commit=remote_apply для финансовых данных (нет потерь при failover)
  • **Cassandra QUORUM** - Leaderless W=2, R=2, N=3 в Netflix для пользовательских настроек и очередей
  • **Google Docs** - Multi-Leader с CRDT-based conflict resolution, позволяет offline-редактирование и concurrent editing
  • **CouchDB** - Multi-Leader для мобильных приложений, конфликты резолвятся через user-visible revision tree
  • **DynamoDB Global Tables** - Multi-Leader across AWS регионов, LWW по умолчанию с опцией custom conflict resolution

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

В 2007 году Amazon опубликовал статью 'Dynamo: Amazon's Highly Available Key-value Store'. Инженеры описали систему без единого leader - кворумы, consistent hashing, vector clocks, hinted handoff. Статья стала манифестом NoSQL движения. Cassandra, Riak, DynamoDB - все реализовали идеи Dynamo. Один из авторов, DeCandia, позже описал как команда убедила скептиков: 'мы не можем позволить одному datacenter-outage остановить корзину покупателя'.

Зачем реплицировать данные

**GitHub, 28 октября 2018. В 22:52 UTC сетевой инженер меняет оборудование в одном дата-центре - трафик кратковременно перебрасывается через Азию. За 24 секунды сети MySQL master-replica рассинхронизируются. Итог: 4 минуты полного outage и 5 часов работы в деградированном режиме.** Репликация данных - это не просто копирование, это архитектурное решение о том, где хранится истина и как она расходится по узлам.

Три причины, по которым системы реплицируют данные, несводимы друг к другу.

ЦельЧто даётПример
ОтказоустойчивостьПри падении узла данные доступны на других репликахPostgreSQL streaming replication: primary упал, standby принимает запросы за секунды
Низкая задержкаЧтение с географически близкого узла вместо cross-region запросаNetflix: 13 регионов AWS, видео читается из ближайшего (p50 < 20 мс вместо 200+ мс)
Масштабирование чтенияНагрузка распределяется по репликам - горизонтальный scale без шардированияInstagram использовал PostgreSQL + 20 read replicas до перехода на Cassandra

**Ключевая сложность репликации** - не копирование данных, а управление изменениями. Каждая запись должна прийти на все реплики в корректном порядке. Если реплика отстала на 1 секунду - за это время могут прийти тысячи транзакций. Что делать с конфликтами? В каком порядке применять? Это и определяет выбор модели репликации.

Реплика - это то же самое, что backup

Реплика - живая копия, синхронизируемая в реальном времени. Backup - snapshot прошлого состояния.

Если выполнить DROP TABLE или массовый DELETE - операция реплицируется на все реплики мгновенно. Backup не затронут. Поэтому репликация не заменяет backup strategy.

Система читает данные в 10 раз чаще, чем пишет. Какая основная цель репликации в этом случае?

Leader-Follower: единственный источник правды

Leader-Follower (Master-Replica) - самая распространённая модель репликации. Один узел-лидер принимает все записи. Follower-узлы получают копию через replication log и обслуживают запросы на чтение.

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

РежимЗадержка записиГарантияПрименение
СинхроннаяВысокая (+RTT до follower)Follower подтверждает - данные точно есть на 2+ узлахPostgreSQL synchronous_commit=on, финансовые данные
АсинхроннаяНизкая (только локальная запись)Eventual - follower обновится когда-нибудьMySQL default, метрики, логи, не критичные данные
ПолусинхроннаяСредняяХотя бы 1 follower подтвердилMySQL semi-sync - компромисс durability vs latency

**Replication lag** - отставание follower от лидера. При асинхронной репликации клиент может прочитать устаревшие данные с реплики. PostgreSQL показывает lag через `pg_stat_replication.replay_lag`. Типичное значение: 10-100 мс в нормальных условиях, секунды - при перегрузке сети или диска.

Синхронная репликация всегда лучше - надёжнее

Синхронная репликация увеличивает latency каждой записи на RTT до follower и блокирует при недоступности follower

PostgreSQL с synchronous_commit=on ждёт подтверждения от всех синхронных standbys. Если один из них временно недоступен - все записи ждут. Поэтому компромисс: хотя бы один синхронный standby (а не все) плюс асинхронные остальные.

Primary падает при асинхронной репликации. Follower успел применить 990 из 1000 транзакций. Что происходит при failover?

Multi-Leader: несколько источников правды

Multi-Leader (Active-Active) - несколько узлов принимают записи. Каждый лидер реплицирует свои изменения на остальных. Главное преимущество - запись в ближайший датацентр без cross-region roundtrip. Главная проблема - **конфликты записи**.

Конфликт записи в multi-leader

DC West получает запрос: `user.name = "Alice"`. DC East одновременно получает: `user.name = "Bob"`. Оба лидера применяют запись локально и отправляют реплику друг другу. Через 80 мс (RTT между US регионами) оба обнаруживают конфликт. Чья версия побеждает?

СтратегияКак работаетПроблема
Last Write Wins (LWW)Побеждает запись с большим timestampКлоки не синхронизированы - NTP погрешность 10+ мс. Cassandra использует LWW по умолчанию
First Write WinsПобеждает первая запись, последующие отклоняютсяТребует координации для определения 'первой' - теряет преимущество multi-leader
Merge / CRDTЗначения объединяются по логике типа данныхРаботает для счётчиков, множеств, но не для произвольных строк
Application logicКонфликт передаётся на уровень приложения для разрешенияСложно реализовать корректно, но максимально гибко

**Где multi-leader применяется:** CouchDB (offline-first sync), Google Docs (CRDT-based), PlanetScale (Vitess multi-region), GitLab Geo (geo-replication). Не применять для финансовых данных и случаев где конфликты неразрешимы без потерь.

CouchDB используется для мобильного приложения с offline-режимом. Пользователь редактирует документ офлайн, синхронизируется позже. Какая стратегия конфликтов подходит лучше?

Leaderless: кворумы вместо лидера

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

УзелДействиеРезультат
Node 1Получает запрос на записьACK
Node 2Получает запрос на записьACK
Node 3НедоступенЗапись не дошла
ИтогКворум W=2 достигнут (2 из 3 ACK)Запись успешна
Конфигурация W/R/NСвойствоИспользуется для
W=1, R=NБыстрая запись, медленное чтениеWrite-heavy системы, логи
W=N, R=1Медленная запись, быстрое чтениеRead-heavy с жёсткой консистентностью
W=2, R=2, N=3Баланс - 1 узел может упастьCassandra по умолчанию (QUORUM)
W=1, R=1Максимальная скорость, нет гарантийEventual consistency, кеши

**Sloppy quorum** - при недоступности нужных реплик Dynamo-style системы пишут на любые W доступных узлов, даже не ответственных за этот ключ. После восстановления - hinted handoff: данные передаются на правильные узлы. Cassandra делает это по умолчанию.

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

W + R > N гарантирует что хотя бы один узел с последней версией участвует в чтении, но не атомарность и не изоляцию

Leaderless системы не поддерживают транзакции между ключами по умолчанию. Два concurrent write на разные реплики могут создать конфликт. W+R>N - необходимое, но недостаточное условие для strong consistency.

Cassandra кластер: N=5, W=3, R=3. Падают 2 узла. Система продолжает принимать записи?

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

  • Рассмотри сервис, которым пользуешься ежедневно (мессенджер, банковское приложение, облачное хранилище). Какую модель репликации он скорее всего использует и почему этот выбор обоснован для конкретного use case?

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

  • ds-08-vector-clocks — Multi-master replication needs vector clocks for conflicts
  • ds-10-crdts — CRDT-based replication is a coordination-free strategy
  • dist-12-consistency — Replication lag directly limits achievable consistency level
  • db-13-transactions
Репликация данных

0

1

Войти