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

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

Цели урока

  • Понимать определение распределённой системы по Лэмпорту и его практический смысл
  • Знать четыре класса сбоев и стратегии защиты от каждого
  • Применять CAP-теорему для выбора БД и архитектуры
  • Различать уровни согласованности от linearizable до eventual

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

  • Базовое понимание сетевых протоколов (TCP, HTTP)
  • Опыт работы с одной БД (PostgreSQL/MySQL/любая SQL)
  • Знание понятия транзакции (ACID)

AWS S3, 28 февраля 2017: одна опечатка одного инженера в одной команде положила половину интернета на 4 часа. 150 млн долларов потерь по индустрии. Это не баг - это природа распределённых систем.

  • **Knight Capital (440 млн долларов за 45 минут)** - один забытый флаг feature toggle на одном из восьми серверов
  • **Ariane 5 (370 млн долларов)** - integer overflow при конвертации в инерциальной системе SRI через 37 секунд после старта
  • **Facebook BGP outage (6 часов, 2021)** - неправильная конфигурация маршрутизации отрезала FB от мира
  • **Cloudflare Regex outage (2 июля 2019)** - один неэффективный regex положил CDN/WAF Cloudflare на 27 минут
  • **Google Spanner** - атомные часы и GPS в каждом дата-центре чтобы обмануть CAP

Лесли Лэмпорт и рождение distributed computing

В 1978 году Лэмпорт опубликовал статью "Time, Clocks, and the Ordering of Events in a Distributed System" - 8 страниц, которые создали целую область. Идея простая: в распределённой системе нет глобального времени, но есть **causal ordering** через логические часы (Lamport timestamps). За эту работу и Paxos он получил Turing Award в 2013. Одна из самых цитируемых статей в распределённых системах (около 14 700 цитирований).

Что такое распределённая система

**28 февраля 2017. 9:37 утра PST. Один инженер Amazon вводит команду в S3 console - опечатка в параметре. За 4 часа из-за этой опечатки лежит половина интернета: Slack, Trello, Quora, Medium, Coursera. Потеряно 150 млн долларов бизнес-выручки за один тикет.** Это и есть распределённая система: миллион вращающихся шестерёнок, любая может остановить всё.

Распределённая система - это когда падение машины, о существовании которой никто не знал, мешает работать.

Лучшего определения за 38 лет не написали. Каждое слово - про реальную боль production-инженера: какая-то VM в дата-центре где-то в Айове, про которую никто не помнил, что от неё зависит auth pipeline - и теперь весь сайт возвращает 503. Независимый сбой и порождает потребность в консенсусе между репликами.

**Формально:** распределённая система - набор независимых компьютеров, которые для пользователя выглядят как единая когерентная система. **Практически:** код, где `network call != function call` - и это разрушает все привычные интуиции.

Масштаб настоящих распределённых систем

СистемаУзлыКлючевая метрика
Bitcoin~17 000 full nodesБез единого центра, byzantine-tolerant
AWS S3Миллионы дисков11 nines durability (потеря файла ~ выигрыш в лотерею 6 раз подряд)
Google SpannerТысячи узлов в 5 регионахГлобальная strong consistency через атомные часы
Cloudflare DNS (1.1.1.1)330+ городовp50 latency 11 мс глобально
Facebook Memcached10 000+ серверов1 миллиард запросов/сек

Распределённая система = просто несколько копий приложения для масштабирования

Распределённая система = набор узлов с независимыми сбоями, частичными отказами и без общего времени

Главная проблема не в производительности, а в том, что каждый узел может упасть, ответить медленно или вернуть устаревшие данные - независимо от других. Один сервер либо работает, либо нет. Распределённая система всегда находится в каком-то промежуточном состоянии: 3 узла из 5 в норме, 1 отвечает с задержкой 2 сек, 1 вернул данные годовой давности.

Какое из утверждений ТОЧНЕЕ всего описывает распределённую систему по Лэмпорту?

Сбой - не исключение, а норма

**Knight Capital, 1 августа 2012. 9:30 EST. Запускают новый код на 8 серверах из 8 - но на одном забыли удалить старый флаг feature toggle. За 45 минут торгов сервер с глюком сделал 4 миллиона трейдов на 7 миллиардов долларов. К концу дня компания потеряла 440 миллионов долларов, через неделю потребовала экстренное вливание капитала, в декабре 2012 поглощена Getco. Один забытый файл на одном сервере из восьми.**

**Главное правило distributed systems:** вопрос не "упадёт ли узел", а "что делает система когда он упал". При 100 узлах с MTBF 1 год сбой происходит каждые 3.65 дня. При 1000 узлах - каждые 8.7 часов. При 10 000 - каждые 52 минуты. **Сбой - это нормальная операция, а не catastrophe.** Этот же blind spot перечислен в восьми заблуждениях.

Четыре класса сбоев (модель Cristian/Schneider)

Тип сбояЧто происходитЗащита
**CRASH**Узел упал и больше не отвечает (kernel panic, OOM, kill)Heartbeat + retry на другом узле кластера
**OMISSION**Узел работает, но молча теряет сообщения (network drop, переполнение буфера)Идемпотентность + acknowledgement
**TIMING**Узел отвечает, но слишком поздно (GC pause, перегрузка CPU, swap)Timeout + retry, circuit breaker
**BYZANTINE**Узел врёт - искажает данные, шлёт противоречивые ответы (bug, hardware failure, malicious)PBFT, Paxos с >2/3 здоровых узлов, signed messages

Сбой омиссии в банковской транзакции

Сервер получил запрос на списание 1000 долларов. Списал. Отправил `200 OK`. Ответ потерялся в сети. Клиент видит timeout. Что делать клиенту? **Ретраить** - возможно двойное списание. **Не ретраить** - возможно списания не было. Решение: каждая транзакция получает уникальный `idempotency-key`. Сервер при повторном запросе с тем же ключом возвращает результат первого, не выполняя списание. Stripe и PayPal так работают с 2010-х.

Anything that can go wrong, will go wrong - and at scale, it will go wrong every Tuesday at 3 PM.

Если использовать надёжное оборудование, сбоев можно избежать

На масштабе тысяч узлов сбой - событие, происходящее каждые часы независимо от качества железа

Pinheiro/Weber/Barroso (Google, FAST 2007) опубликовали данные: AFR около 2% за первый год, 8% за второй, 8.6% за третий. На 100 000 дисков это тысячи отказов в год. Никакое железо не отменит статистику. Решение - проектировать систему так, чтобы сбой узла был routine event с автоматическим восстановлением.

При 1000 серверах с MTBF (mean time between failures) = 1 год, как часто в кластере что-то падает?

CAP-теорема - выбор из трёх

**Эрик Брюер, 2000, конференция PODC. Гипотеза:** распределённая система не может одновременно гарантировать три свойства - **C**onsistency, **A**vailability, **P**artition tolerance. **2002:** Сет Гилберт и Нэнси Линч из MIT доказали это формально. Теперь это закон, как термодинамика. Полный разбор - в уроке про CAP.

  • **Consistency (C)** - все узлы видят одинаковые данные в один момент времени. Записал на одном - прочитал актуальное на любом другом.
  • **Availability (A)** - каждый запрос получает ответ (успех или ошибка), без зависаний. Ни один live узел не молчит.
  • **Partition tolerance (P)** - система продолжает работу при разрыве сети между узлами. В реальном мире сеть рвётся всегда, поэтому P не опция.

**Практическая трактовка:** P неизбежен (сети рвутся). Поэтому реальный выбор - **CP или AP**. Что приоритетнее когда узлы потеряли связь: точные данные ценой недоступности (CP) или какие-то данные ценой возможной устаревшести (AP).

Реальные системы и их выбор

СистемаТипПочему
PostgreSQL (single primary)CPЕсли primary недоступен - запись отвергается. Финансовые данные требуют точности.
MongoDB (с majority writes)CPПри partition меньшая часть кластера становится read-only.
DynamoDBAPEventual consistency по умолчанию - предпочитает доступность для shopping cart.
CassandraAPTunable consistency - можно выбрать на каждый запрос.
etcd / Consul (Raft)CPКоординация кластера - лучше отказать, чем дать конфликтные конфиги.
DNSAPОбновление распространяется часами - устаревшие записи лучше, чем недоступный домен.

**Распространённая ошибка:** считать CAP бинарным выбором на всю систему. На практике даже одна БД делает разный выбор для разных операций (Cassandra: `consistency_level` per query). Современный подход - **PACELC**: при Partition выбор между A и C, **Else** между Latency и Consistency.

Банк выбирает БД для хранения балансов счетов. Какой trade-off корректнее?

Спектр согласованности

**Strong consistency vs Eventual consistency** - это не два варианта, а полюса спектра. Между ними - десяток уровней, каждый с своим trade-off latency vs точность.

УровеньГарантияLatencyПример
LinearizableЗапись видна всем мгновенно (как single machine)Высокая (10-100мс глобально)Google Spanner, etcd
SequentialВсе видят операции в одном порядкеСредняяZooKeeper read consistency
CausalСвязанные причинно операции в порядкеНизкаяRiak, COPS
Read-after-write (RYW)Своя запись видна сразу, чужие eventuallyНизкаяSession consistency в DynamoDB
EventualКогда-нибудь все узлы сойдутсяМинимальнаяDynamoDB, Cassandra default

Google Spanner: как обмануть CAP

Spanner - первая глобальная strong consistency БД. Ключ - **TrueTime API**: каждый дата-центр имеет атомные часы и GPS-приёмники. API возвращает не точное время, а интервал `[earliest, latest]` с гарантированной погрешностью (обычно 7мс). Транзакция ждёт пока интервал пройдёт - получает глобально упорядоченные timestamps без координации. Механика логического и физического времени разбирается в уроке про часы.

**Цена strong consistency:** каждый коммит блокируется на несколько мс ожидания. Пропускная способность Spanner - тысячи tx/sec на узел, а не миллионы как у DynamoDB. Поэтому Google использует Spanner для финансов и Ads, а для поиска - eventually consistent системы.

Главное из урока

  • Распределённая система = независимые сбои + частичные отказы + нет общего времени (Lamport 1987)
  • На масштабе тысяч узлов сбой происходит каждые часы - норма, а не исключение
  • 4 класса сбоев: crash, omission, timing, byzantine - каждый требует своих защит
  • CAP-теорема: P неизбежен, выбор между CP (точность) и AP (доступность)
  • Consistency - спектр от linearizable до eventual, выбор на основе бизнес-требований

Что дальше в курсе

Каждая концепция этого урока разворачивается в отдельную тему.

  • CAP-теорема и PACELC — Формальные доказательства и нюансы выбора
  • Консенсус (Paxos, Raft) — Как узлы договариваются при сбоях

Ключевые понятия

  • Распределённая система - это набор узлов, каждый из которых не знает о сбое другого (определение Лэмпорта)
  • CAP-теорема: из трёх свойств (Consistency, Availability, Partition tolerance) реально выбирают два - и P всегда обязательно, значит выбор между C и A
  • CP-системы (например, ZooKeeper, HBase) при разрыве сети отказывают запросам, но данные всегда согласованы
  • AP-системы (например, Cassandra, DynamoDB) продолжают работать при разрыве, но разные узлы могут вернуть разные данные
  • Четыре класса сбоев: crash (узел упал), omission (пакет потерян), timing (ответ опоздал), Byzantine (узел врёт)
  • Уровни согласованности от сильной к слабой: linearizable - sequential - causal - eventual; каждый следующий быстрее, но менее предсказуем для клиента

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

  • Любой ежедневный сервис (банковское приложение, мессенджер, навигатор) - какой trade-off CAP он скорее всего выбрал и почему именно такой?

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

  • ds-02-cap-theorem — CAP формализует partition trade-off, заявленный здесь
  • ds-03-consensus — Paxos и Raft решают согласие при описанных тут сбоях
  • ds-05-replication — Стратегии репликации опираются на независимые сбои
  • sd-10-microservices — Любой mesh микросервисов наследует модель сбоев Лэмпорта
  • alg-01-big-o — Интуиция сложности нужна для рассуждений о масштабе кластера
  • st-01-feedback-loops — Координация в организациях даёт ту же динамику частичных сбоев
  • ibd-21-docker-k8s-interview
  • net-01-intro
Введение в распределённые системы

0

1

Войти

Логические часы
— Lamport timestamps, vector clocks для упорядочивания событий
  • Репликация — Leader/follower, multi-leader, leaderless подходы
  • CRDTs — Конфликт-фри структуры данных для AP-систем
  • Как Google Spanner достигает глобальной strong consistency без огромного latency?