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

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

Разработчику Архитектору
Теория данных (раздел 3)

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

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

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

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

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, очередь, воркеры) — в System Design — карта тем и подготовка.

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

Клиент → 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. Итоги раздела · чек-лист