Перейти к основному содержимому

12 концепций архитектуры распределённых систем

Разработчику Архитектору

Ниже — короткая шпаргалка по идеям, которые встречаются в любом высоконагруженном веб-сервисе. Каждый пункт — одна фраза «зачем» и ссылка, куда разобрать детали в энциклопедии.

Полная карта system design (порядок изучения от сетей к очередям, пять инженерных рычагов, типовой контур, каркас собеседования) — в System Design — карта тем и подготовка.

Сначала фундамент

Балансировка, кэш и Kafka имеют смысл после HTTP/TCP/DNS и модели данных (индексы, репликация). Маршрут по шагам — в 143.md; Kubernetes — после понимания этого контура.

Как пользоваться

Сначала пробегите таблицу целиком, затем откройте 2–3 темы, которые уже встречаются в вашем проекте (например, кэш + балансировщик + rate limit на API). Для микросервисов логичное продолжение — экосистема технологий, девять компонентов продакшн-стека и паттерны MSA, инженерия устойчивости. Для продукта с LLM те же приёмы ложатся на семь слоёв LLM-стека (слои 5–6).


Сводная таблица

КонцепцияЗачемУглубление
1Балансировка нагрузкиРаспределяет входящие запросы между несколькими серверами, снимает перегрузку с одного узлаГоризонтальное масштабирование, веб-серверы, глоссарий «Балансировка нагрузки»
2КэшированиеХранит часто читаемые данные в памяти, снижает задержку и нагрузку на БДRedis, HTTP-кэш, веб-стек
3CDNРаздаёт статику с edge-узлов ближе к пользователюВеб-серверы и CDN, масштабирование веба
4Очередь сообщенийРазвязывает продюсера и потребителя: задачи обрабатываются асинхронноБрокеры, RabbitMQ, Kafka
5Publish–SubscribeОдно событие получают все подписчики топикаТипы взаимодействия, событийная архитектура, Redis Pub/Sub
6API GatewayЕдиная точка входа: маршрутизация, auth, лимиты, агрегацияПаттерны MSA §5, проектирование API, REST в инфраструктуре
7Circuit BreakerПри серии сбоев зависимости перестаёт «долбить» её запросамиИнженерия устойчивости, веб-паттерны
8Service DiscoveryРеестр живых экземпляров сервисов в динамическом кластереПаттерны MSA §4, влияние инфраструктуры, Kubernetes Services
9ШардированиеДелит датасет по ключу на несколько серверов; ключ задаёт равномерность нагрузки§9 ниже, масштабируемость, РСУБД § шардинг, MongoDB
10Rate limitingОграничивает число запросов клиента за окно времени§10 — пять алгоритмов, проектирование API, уязвимости API
11Consistent hashingРаскладывает ключи по кольцу узлов; при добавлении узла переносится меньше данныхГлоссарий, Redis Cluster
12AutoscalingДобавляет или убирает инстансы по метрикам нагрузкиГоризонтальное масштабирование, HPA в Kubernetes, облачные технологии

1. Балансировка нагрузки (Load Balancing)

Балансировщик принимает трафик от клиентов и направляет его на один из однотипных backend-инстансов. Частые алгоритмы:

АлгоритмСутьКогда уместен
Round RobinПо очереди на каждый здоровый узелОднородные запросы и равная мощность инстансов
Least ConnectionsНа узел с меньшим числом активных соединенийДолгие запросы (файлы, WebSocket, тяжёлые API)
WeightedДоля трафика пропорциональна весу узлаРазная мощность машин в пуле
IP hash / consistent hashingКлиент или ключ «прилипает» к узлуЛокальный кэш на инстансе; шарды по ключу — §11

Дополнительно — health-check и исключение нездоровых узлов из пула.

Типичные продукты: Nginx, HAProxy, Envoy, облачные ALB/NLB. Балансировка даёт и отказоустойчивость: нездоровый узел исключают из пула.

Связка с проектированием: приложение должно быть stateless (сессия и данные — во внешнем хранилище), иначе все запросы одного пользователя «прилипнут» к одному серверу.


2. Кэширование (Caching)

Перед обращением к медленной БД проверяют кэш (Redis, Memcached, in-process). Попадание в кэш — ответ из памяти за миллисекунды; промах — чтение из БД и запись в кэш.

Уровни кэша:

  • браузер и CDN — статика и ответы с Cache-Control;
  • приложение — горячие объекты и сессии;
  • СУБД — буферный пул и материализованные представления.

Важно заранее выбрать политику инвалидации (TTL, событие «данные изменились»), иначе пользователи увидят устаревшие данные. В Redis при нехватке RAM срабатывает eviction (allkeys-lru, volatile-ttl и др.) — таблица maxmemory-policy в главе про Redis.


3. CDN (Content Delivery Network)

CDN — сеть edge-серверов, которые кэшируют статику (и иногда HTML/API) рядом с пользователем. Запрос к cdn.example.com часто не доходит до origin в вашем дата-центре.

Снижается latency и нагрузка на origin. DNS направляет клиента на ближайший PoP. Для динамики используют edge-функции (Workers, Lambda@Edge).


4. Очередь сообщений (Message Queue)

Продюсер кладёт сообщение в очередь и продолжает работу. Потребители забирают задачи в своём темпе. Так развязывают пики нагрузки и длинные операции (отправка писем, генерация отчётов). Для почты поверх очереди нужны ещё state machine, suppression и webhooks провайдера — email-рассылка как распределённая система.

Гарантии доставки (at-most-once, at-least-once, exactly-once) и порядок сообщений — отдельное проектное решение; см. брокеры.


5. Publish–Subscribe

В модели pub/sub отправитель публикует событие в топик, а все подписчики получают копию. Это broadcast: один факт — много реакций (уведомления, аналитика, синхронизация read-моделей).

Отличие от очереди: в классической очереди сообщение обычно обрабатывает один consumer; в pub/sub — много независимых подписчиков.


6. API Gateway

Шлюз API — фасад для внешних клиентов (браузер, мобильное приложение, партнёр). Он маршрутизирует /orders → сервис заказов, проверяет JWT, режет трафик по rate limit, может собрать ответ из нескольких внутренних вызовов.

Внутренние сервисы остаются за периметром; клиент не знает их адресов и не держит десятки контрактов.


7. Circuit Breaker (предохранитель)

Три состояния:

СостояниеПоведение
ClosedВызовы идут к зависимости как обычно
OpenПосле порога ошибок вызовы сразу отклоняются (fallback, кэш, ошибка 503)
Half-OpenПробные запросы проверяют, восстановилась ли зависимость

Цель — не усугубить падение зависимого сервиса лавиной retry и не блокировать свои потоки на таймаутах.


8. Service Discovery

В Kubernetes и облаке IP инстансов меняются при каждом деплое. Service discovery (Consul, Eureka, etcd, DNS Kubernetes) хранит актуальный список host:port и health.

Client-side discovery — клиент сам выбирает инстанс из реестра. Server-side — запрос идёт на балансировщик, который смотрит в реестр.


9. Шардирование (Sharding)

Шардинг (горизонтальное партиционирование) — распределение данных одной логической базы по нескольким серверам (шардам). Каждый шард хранит подмножество строк; вместе они образуют полный датасет. Правильно выбранный ключ шарда напрямую влияет на производительность и равномерность нагрузки.

Зачем шардинг

  • Масштабируемость — объём и интенсивность записи растут за пределы одного сервера.
  • Производительность — нагрузка распределяется между узлами.
  • Доступность — сбой одного шарда затрагивает только его данные; остальные продолжают обслуживать запросы (при репликации каждого шарда добавляется отказоустойчивость на уровне данных).

Шардинг увеличивает пропускную способность записи и ёмкость; для отказоустойчивости шарды обычно реплицируют отдельно.

Типы шардинга

ТипСутьПример
По диапазону (range)Данные режутся по интервалам значения ключаЗаказы с id 0…999 — shard 1, 1000…1999 — shard 2; товары до 75 — один шард, 76–150 — другой
По справочнику (directory)Каталог сопоставляет значение ключа и номер шардаРегион EU → shard 2, RU → shard 1; перенос «горячего» региона — правка каталога
По ключу / хешу (key-based)hash(shard_key) → shard_id даёт более равномерное распределениеОдин user_id всегда попадает на один шард

Диапазон и справочник удобны, когда запросы локализованы по известному ключу (регион, период). Хеш-схема снижает перекос при равномерных ключах, если поле выбрано осознанно.

Выбор ключа шарда

Три критерия, которые стоит проверить до продакшена:

  1. Кардинальность — много уникальных значений ключа; данные равномерно раскладываются по шардам. Ключ с двумя–тремя значениями даёт 2–3 перегруженных шарда.
  2. Частота (распределение) — значения встречаются примерно с одной частотой. Редкий, но «горячий» ключ (мега-аккаунт, общий каталог) создаёт hot partition — один шард перегружен.
  3. Монотонность — время, автоинкремент и последовательные ID направляют все новые записи на последний шард; остальные простаивают. Для таких полей используют составной ключ (tenant_id + id) или хеш от стабильного бизнес-идентификатора.

На практике также требуют локальность запросов (один запрос — один шард) и предсказуемый маршрут без полного сканирования кластера.

Маршрутизация запросов к шарду

ПаттернКто выбирает шард
Узлы, знающие топологиюКлиент подключается к любому узлу; узел знает карту и перенаправляет запрос на нужный шард
Выделенный маршрутизаторПрокси (mongos, Vitess): приложение шлёт запрос в один endpoint, маршрутизация скрыта
Шард-aware клиентЛогика в приложении: по user_id вычисляется шард и открывается соединение напрямую

Простое hash(key) % N при изменении числа узлов N перекладывает почти все ключи; для плавного роста кластера применяют consistent hashing (см. §11).

Ограничения

  • Транзакции и JOIN между шардами — дорого или недоступны; границы данных проектируют вокруг ключа шарда.
  • Перебалансировка при добавлении шардов — миграция данных и двойная запись на переходный период.
  • Партиционирование внутри одной СУБД на одном сервере ускоряет обслуживание таблицы, но не снимает лимит железа — см. партиционирование.

Углубление: Масштабируемость и параллелизм, репликация и шардинг в РСУБД, MongoDB, глоссарий «Шардинг».


10. Rate Limiting

Лимит запросов (rate limiting) ограничивает, сколько запросов клиент (IP, API-ключ, sub из JWT, tenant) может отправить за интервал времени. Цели — защита от злоупотреблений, brute-force, случайных DDoS и перегрузки downstream-сервисов при ошибках клиента.

Лимит обычно ставят на API Gateway, reverse-proxy (Nginx, Envoy) или в middleware приложения; счётчик часто хранят в Redis при нескольких инстансах. При превышении — 429 Too Many Requests и по возможности Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (имена заголовков не стандартизированы единым RFC, но распространены). Подробнее про контракт с клиентом — проектирование API — лимиты и квоты, код 429.

Ниже — пять распространённых алгоритмов. Выбор зависит от того, нужны ли кратковременные всплески (burst) или ровный исходящий поток, и сколько памяти вы готовы тратить на точность.

Сводка алгоритмов

АлгоритмПамятьТочностьГлавный плюс
Fixed Window CounterНизкаяНизкая (граница окна)Простая реализация, один счётчик на окно
Sliding Window LogВысокаяВысокаяТочный лимит за последние N секунд
Sliding Window CounterНизкаяСредняя–высокаяКомпромисс: мало памяти, без «двойного» лимита на стыке окон
Token BucketНизкаяВысокаяДопускает burst, если накопились токены
Leaky BucketНизкаяВысокаяВыравнивает поток на выходе, защищает сервис от рывков

1. Fixed Window Counter (фиксированное окно)

Время делится на непересекающиеся интервалы (например, каждую минуту с :00). Внутри окна ведётся счётчик запросов; при достижении capacity остальные запросы отклоняются до начала следующего окна.

Минус: на стыке двух окон клиент может отправить почти двойной лимит за короткий промежуток (например, 100 запросов в 00:59 и ещё 100 в 01:00). Для многих публичных API это приемлемо; для жёстких SLA — смотрите скользящие окна.

2. Sliding Window Log (журнал скользящего окна)

Для каждого принятого запроса сохраняется метка времени. Перед обработкой нового запроса удаляются записи старше окна (например, старше 60 секунд), затем считается число оставшихся. Если count < limit — запрос принимается и в лог добавляется новая метка.

Плюс: нет артефакта на границе фиксированных окон. Минус: память и работа с множеством меток растут с числом клиентов и частотой запросов. В Redis типичная реализация — sorted set (ZSET) с атомарным Lua-скриптом, см. Redis — rate limiter.

3. Sliding Window Counter (счётчик скользящего окна)

Гибрид: хранятся счётчики текущего и предыдущего фиксированного окна (например, две «минуты»). Оценка нагрузки за последние 60 секунд — взвешенная сумма: доля предыдущего окна, ещё попадающая в интервал, плюс счётчик текущего окна. Памяти мало, поведение ближе к скользящему окну, чем у одного fixed window.

4. Token Bucket (ведро токенов)

В «ведро» с максимальной ёмкостью токены поступают с постоянной скоростью (например, 10 токенов в секунду). Каждый запрос забирает один токен. Есть токен — запрос проходит; ведро пустое — отказ (429 или очередь, если так заложено в продукте).

Когда уместен: публичные API и мобильные клиенты, где кратковременный burst допустим (пользователь открыл экран и дернул несколько эндпоинтов сразу), но средняя скорость должна оставаться в лимите. Тот же принцип лежит в limit_req … burst= в Nginx и в Token Bucket Filter (tbf) в tc Linux — см. обратный прокси, шейпинг трафика.

5. Leaky Bucket (протекающее ведро)

Входящие запросы попадают в очередь (FIFO) фиксированного размера; из ведра они «протекают» на обработку с постоянной скоростью. Очередь переполнена — новые запросы отбрасываются. На выходе поток ровный, burst на backend не попадает.

Когда уместен: защита узкого ресурса (БД, внешний API), где важна стабильная скорость обработки, а не разрешение всплесков. Отличается от token bucket: token bucket разрешает burst на входе (пока есть токены), leaky bucket сглаживает поток к downstream.

Как выбрать

ЗадачаЧастый выбор
Простой лимит «1000 запросов в час» на gatewayFixed window или sliding window counter
Строгий лимит «не более 60 в минуту» без провала на стыке минутSliding window log или counter
API с редкими всплесками, средняя скорость важнее пикаToken bucket
Защита БД/воркера от волны одновременных запросовLeaky bucket или очередь + фиксированный pool воркеров

Ключ лимита задают явно: IP, API-Key, user_id, комбинация tenant + route. На /login и /reset-password лимиты строже, чем на чтение каталога — см. безопасность API.

Троттлинг и rate limit
Троттлинг (throttling) в эксплуатации — общее «дросселирование» нагрузки (CPU cgroup, 429, очередь). Rate limiting — конкретный алгоритм подсчёта запросов во времени. См. также троттлинг в администрировании.


11. Consistent Hashing

Обычный hash(key) % N при добавлении узла перекладывает почти все ключи. Consistent hashing размещает узлы и ключи на кольце: ключ принадлежит первому узлу по часовой стрелке. При появлении нового узла переезжает только его сегмент кольца.

Используют в распределённых кэшах, балансировщиках, шардах (виртуальные ноды на кольце уменьшают перекос нагрузки).


12. Autoscaling

Автомасштабирование по метрикам (CPU, RPS, длина очереди) добавляет или удаляет инстансы. В Kubernetes — Horizontal Pod Autoscaler; в облаке — Auto Scaling Groups.

Связано с горизонтальным масштабированием: stateless-приложение, балансировщик, observability. Scale-down требует graceful shutdown, чтобы не оборвать активные запросы.


Типовые цепочки

Полная схема продакшн-приложения на микросервисах (gateway, registry, авторизация, брокер, Prometheus, ELK) — в Паттернах MSA. Скелет «90% масштабируемых систем» (CDN, stateless API, кэш, primary/read replica, очередь, воркеры) — в 143.md.

Быстрый ответ пользователю

Клиент → CDN (статика) → API Gateway (auth + rate limit) → балансировщик → сервис → кэш → при промахе read replica (или primary на запись).

Запись и фоновая работа

API пишет в primary → репликация на read-копии → событие в очередь (или CDC/outbox) → воркеры (уведомления, аналитика, пересчёт ленты) без блокировки HTTP-ответа.

Устойчивость к сбоям партнёра

Сервис → circuit breaker на вызов внешнего API → при open — ответ из кэша или очередь на повтор позже.

Рост нагрузки

Метрики → autoscaling → новые поды → service discovery обновляет реестр → балансировщик начинает слать им трафик.


Слой сетевых служб

Балансировщик, CDN, API Gateway и кэш из таблицы выше работают поверх базовых сетевых служб. Их порты и протоколы постоянно всплывают при проектировании и инцидентах:

РольПримерыПортСвязь с архитектурой
ИменаDNS53Service discovery и CDN направляют клиента на нужный IP
Вход в APIHTTPS / HTTP/3443Gateway, rate limit, TLS termination
ДанныеPostgreSQL, MySQL5432, 3306Шардирование, реплики, connection pool
ИдентификацияOAuth 2.0 / OIDC, LDAP443, 389/636Единый вход, корпоративный каталог
ОперацииSSH22Деплой, туннель к БД, диагностика

Полная таблица по шести группам (DHCP, NTP, почта, VPN и др.) — Сетевые сервисы по ролям. Учебный контекст портов и сокетов — сеть и интернет, основы.


Что читать дальше

  1. System Design — карта тем и подготовка · Масштабируемость и параллелизм · NFR
  2. Распределённые системы · Выбор лидера — Raft, Paxos, ZAB · PACELC
  3. Микросервисы и интеграция
  4. Итоги раздела · чек-лист

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").