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

> Системы из нескольких компьютеров, взаимодействующих по сети и выглядящих для пользователя как одно целое; ключевые проблемы — частичные сбои, задержки, время, консенсус и репликация.

Источник: https://llmdocs.ru/wiki/distributed-systems/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Определение**: несколько узлов, общающихся сообщениями, без общей памяти и общих часов
- **Ключевые проблемы**: частичные сбои, ненадёжная сеть, отсутствие глобального времени
- **Консенсус**: Paxos (1989), Raft (2014)
- **Основные работы**: Лэмпорт — «Time, Clocks…» (1978); FLP (1985)
- **Книги**: «Designing Data-Intensive Applications» (Клеппман)
- **Примеры**: Kubernetes, etcd, Kafka, Cassandra, Spanner
**Распределённая система** — набор независимых компьютеров (узлов), которые общаются только сообщениями по сети и вместе решают одну задачу так, что для пользователя они выглядят как единое целое. Почти любой современный сервис распределён: веб-приложение с базой данных и кэшем, кластер [Kubernetes](https://llmdocs.ru/wiki/kubernetes.md), реплицированная база, очередь сообщений, [CDN](https://llmdocs.ru/wiki/cdn.md). Распределение нужно ради масштабирования, отказоустойчивости и близости к пользователям, но приносит фундаментальные трудности, которых нет в программе на одном компьютере.

## Почему это трудно

В одном процессе вызов функции либо выполняется, либо программа падает целиком. В распределённой системе возможны **частичные сбои**: один узел работает, другой завис, сеть между ними теряет пакеты. Отправив запрос и не получив ответа, узел не может отличить три ситуации — запрос потерялся, получатель упал, или ответ потерялся по дороге, а действие уже выполнено.

Известный список **заблуждений распределённых вычислений** (Питер Дойч и коллеги из Sun, 1990-е) перечисляет ложные предположения новичков:[5]

1. сеть надёжна;
2. задержка равна нулю;
3. пропускная способность бесконечна;
4. сеть безопасна;
5. топология не меняется;
6. администратор один;
7. передача данных бесплатна;
8. сеть однородна.

## Время и порядок

У узлов нет общих часов: системное время расходится, синхронизация по NTP даёт точность в миллисекунды, а часы могут прыгать назад. Поэтому нельзя надёжно упорядочить события по меткам времени с разных машин. Лесли Лэмпорт в работе 1978 года предложил **логические часы** — счётчики, отражающие причинно-следственный порядок «произошло раньше» без физического времени.[1] Развитие идеи — векторные часы и гибридные логические часы. Google Spanner решает задачу иначе — атомными часами и GPS с явной оценкой погрешности (TrueTime).

## Репликация

Хранение копий данных на нескольких узлах обеспечивает отказоустойчивость и масштабирование чтения (см. [Репликация баз данных](https://llmdocs.ru/wiki/replication.md)):

| Схема | Как работает | Компромисс |
|---|---|---|
| **Лидер — последователи** | записи идут на лидера, реплики копируют | просто; при отказе лидера нужно переключение |
| **Несколько лидеров** | запись в любом дата-центре | конфликты одновременных изменений |
| **Без лидера** (Dynamo-стиль) | запись и чтение кворумом из N узлов | гибко; согласованность в конечном счёте |

Синхронная репликация гарантирует, что данные не потеряются, но медленнее и зависит от доступности реплик; асинхронная быстрее, но при отказе лидера последние записи могут пропасть. Выбор между согласованностью и доступностью при сбоях сети формализует [CAP-теорема](https://llmdocs.ru/wiki/cap-theorem.md). Для данных, которые не помещаются на один узел, применяют [шардирование](https://llmdocs.ru/wiki/sharding.md).

## Консенсус

Многие задачи — выбор лидера, распределённые блокировки, атомарная фиксация, хранение конфигурации — сводятся к **консенсусу**: несколько узлов должны договориться об одном значении, даже если часть из них отказала. Теорема FLP (1985) доказывает, что в полностью асинхронной сети детерминированный консенсус невозможен даже при одном сбое;[3] практические алгоритмы обходят это с помощью тайм-аутов и гарантируют безопасность всегда, а продвижение — когда сеть ведёт себя разумно.

- **Paxos** (Лэмпорт) — классический алгоритм, известный сложностью понимания.
- **Raft** (2014) — создан специально понятным: выбор лидера по срокам (terms), репликация журнала, большинство голосов.[2] Используется в etcd (хранилище [Kubernetes](https://llmdocs.ru/wiki/kubernetes.md)), Consul, CockroachDB, Kafka (KRaft).

Кластер из 2f + 1 узлов переживает отказ f узлов: из трёх — одного, из пяти — двух. Поэтому кластеры консенсуса имеют нечётный размер.

## Надёжная работа с сетью

- **Тайм-ауты** на каждый сетевой вызов — без них один зависший сервис останавливает всю цепочку.
- **Повторы с экспоненциальной задержкой и случайным разбросом** (jitter), чтобы не создать лавину запросов.
- **Идемпотентность** — повторный запрос не должен списать деньги дважды; используют ключи идемпотентности.
- **Автоматический выключатель** (circuit breaker) — перестать вызывать сервис, который явно не работает.
- **Асинхронный обмен** через очереди и журналы событий (Kafka, RabbitMQ) — развязывает сервисы по времени.
- **Семантика доставки**: «не более одного раза», «хотя бы один раз», а «ровно один раз» на практике достигается сочетанием повторов и идемпотентной обработки.

Многие из этих механизмов вынесены в инфраструктуру — [Service mesh](https://llmdocs.ru/wiki/service-mesh.md), балансировщики и клиентские библиотеки.

## Наблюдаемость и тестирование

Отладка распределённой системы требует [распределённой трассировки](https://llmdocs.ru/wiki/opentelemetry.md) и сквозных идентификаторов запросов. Для проверки поведения при сбоях используют хаос-инжиниринг (намеренное отключение узлов и внесение задержек), тесты в духе Jepsen и формальную верификацию алгоритмов — например, на языке TLA+, который разработал Лэмпорт и применяют AWS и другие компании.

## Литература

Основное современное введение — книга Мартина Клеппмана «Designing Data-Intensive Applications» («Высоконагруженные приложения»).[4] Классические работы — статьи Лэмпорта, работа FLP и статья о Raft вместе с его интерактивной визуализацией.[6]

## См. также

- [CAP-теорема](https://llmdocs.ru/wiki/cap-theorem.md)
- [Репликация баз данных](https://llmdocs.ru/wiki/replication.md)
- [Конкурентность и параллелизм](https://llmdocs.ru/wiki/concurrency-parallelism.md)
- [Kubernetes](https://llmdocs.ru/wiki/kubernetes.md)

## Источники

1. [Lamport — Time, Clocks, and the Ordering of Events in a Distributed System (1978)](https://lamport.azurewebsites.net/pubs/time-clocks.pdf)
2. [Ongaro, Ousterhout — In Search of an Understandable Consensus Algorithm (Raft, 2014)](https://raft.github.io/raft.pdf)
3. [Fischer, Lynch, Paterson — Impossibility of Distributed Consensus with One Faulty Process (1985)](https://groups.csail.mit.edu/tds/papers/Lynch/jacm85.pdf)
4. [Kleppmann — Designing Data-Intensive Applications (O'Reilly)](https://dataintensive.net/)
5. [Deutsch et al. — Fallacies of Distributed Computing](https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing)
6. [Raft — визуализация и реализации](https://raft.github.io/)
