Компьютерные сети

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

В 2017 году Amazon S3 упал на 4 часа из-за typo в команде. Это затронуло половину интернета - Slack, Trello, IFTTT. Распределённые системы выглядят надёжнее, но их failure modes сложнее и коварнее.

  • **GitHub** - partial outage когда часть git операций работает, часть нет
  • **AWS S3** - 11 девяток durability, но availability outages случаются
  • **Google Spanner** - globally distributed DB с CAP trade-offs

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

  • TCP: Congestion Control

Network Partitions

**Network Partition (split-brain)** - ситуация, когда часть узлов системы не может связаться с другой частью. Оба сегмента работают, но не видят друг друга. Для распределённых систем это не edge case, а регулярная реальность.

Представь: datacenter в Москве и datacenter в Лондоне. Оба работают, но канал между ними временно недоступен. Каждый сегмент думает, что он единственный живой. Что делать? Продолжать работу (риск конфликтов) или остановиться (потеря доступности)?

**CAP теорема:** При network partition система может гарантировать либо Consistency (все узлы видят одинаковые данные), либо Availability (система отвечает на запросы). Нельзя иметь оба одновременно при partition.

**Как обнаружить partition?** Heartbeat между узлами. Если узел не отвечает на heartbeat за timeout - он считается недоступным. Проблема: timeout 5 секунд vs 30 секунд - баланс между false positives и временем обнаружения реальных проблем.

Что означает CAP теорема для распределённой системы при network partition?

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

**Latency** в распределённых системах - не просто задержка сети. Это комбинация: network RTT + serialization + queuing + processing. И главное - latency имеет **распределение**, а не фиксированное значение.

Средняя latency 10ms ничего не говорит о worst case. p99 latency (99-й перцентиль) может быть 500ms. А p99.9 - 2 секунды. Для пользователей важны именно tail latencies.

**Fan-out amplification:** Если сервис делает 10 параллельных запросов, p99 финального ответа определяется самым медленным. 10 запросов с p99=100ms дают p99 финала ≈ 400ms (не 100ms!).

**Стратегии борьбы с tail latency:** • **Hedged requests** - отправь запрос на 2 сервера, верни первый ответ • **Timeouts** - не жди бесконечно, fail fast • **Circuit breaker** - если сервис деградирует, перестань его вызывать • **Load shedding** - отбрасывай лишнюю нагрузку до очереди

Если сервис делает 10 параллельных запросов с p99=100ms каждый, какой примерно будет p99 общего времени?

Partial Failures

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

Отправил запрос, не получил ответа. Что случилось? Сервер упал? Сеть потеряла пакет? Сервер обработал запрос, но ответ потерялся? Сервер завис на 30 секунд и ответит позже? **Невозможно точно знать.**

**Идемпотентность - ключ к retry.** Если операция идемпотентна (повторное выполнение даёт тот же результат), можно безопасно retry. `GET /user/123` - идемпотентен. `POST /transfer?amount=100` - НЕ идемпотентен (без idempotency key).

**Стратегии обработки partial failures:** • **Retry with backoff** - повторяй с увеличивающейся задержкой • **Idempotency keys** - безопасный retry для non-idempotent операций • **Circuit breaker** - не retry к явно сломанному сервису • **Saga pattern** - компенсирующие транзакции для отмены частичных операций

Клиент отправил запрос на перевод денег и получил timeout. Что он точно знает?

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

**Распределённые системы используют сеть по-особому:** retries, timeouts, circuit breakers, service discovery. Это не просто HTTP запросы - это целая инфраструктура для reliable communication.

**Service Discovery** - как найти IP:port сервиса? Hardcode? DNS? Consul/etcd? В Kubernetes - CoreDNS + Service resources. В AWS - Cloud Map или ALB.

**Health checks в распределённых системах:** • **Liveness** - процесс жив? (restart если нет) • **Readiness** - готов принимать трафик? (убрать из load balancer) • **Startup** - завершилась инициализация? (не убивать раньше времени)

Timeout значит, что сервер упал

Timeout означает 'я не знаю что случилось' - сервер мог обработать запрос

В распределённой системе timeout может означать: потерю запроса, потерю ответа, медленный сервер, network partition. Без дополнительной проверки (query состояния, idempotency key) невозможно знать результат

Зачем добавлять jitter к exponential backoff при retry?

Итоги

  • **Network Partition** - узлы работают, но не видят друг друга (CAP trade-off)
  • **Latency distribution** - p99 важнее average; fan-out amplifies tail latency
  • **Partial Failure** - часть системы может работать, часть нет, и это неизвестно
  • **Idempotency** - ключ к безопасным retry при неизвестном состоянии
  • **Resilience patterns** - retry + backoff + jitter, circuit breaker, bulkhead

Связанные темы

Понимание сетевых проблем - основа для изучения RPC и message queues:

  • TCP Congestion — Congestion control влияет на latency и retransmits
  • RPC — RPC абстрагирует сетевые вызовы, но не проблемы

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

  • Какие операции в твоём приложении идемпотентны, а какие нет?
  • Как бы ты реализовал idempotency key для платёжного API?
  • Какой timeout выбрать: слишком короткий → false failures, слишком длинный → медленный UX?

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

  • sd-01-intro
Сети распределённых систем

0

1

Войти