Теория
Designing Data-Intensive Applications
Библия распределённых систем от Martin Kleppmann
Масштабируемость — это способность системы обрабатывать растущую нагрузку путём добавления ресурсов. В этой главе мы рассмотрим фундаментальные паттерны и принципы, которые лежат в основе проектирования высоконагруженных распределённых систем.
Scale Cube: Три оси масштабирования
Модель Scale Cube описывает три измерения масштабирования приложений:
X-axis Scaling
Запуск N идентичных копий приложения за Load Balancer. Каждая копия обрабатывает 1/N нагрузки.
Y-axis Scaling
Разделение приложения на микросервисы. Каждый сервис отвечает за конкретную функцию или домен.
Z-axis Scaling
Каждый сервер обрабатывает только подмножество данных. Роутинг по customer_id, region и т.д.
Подробнее
CAP теорема
Формальное определение, доказательство и практические примеры.
CAP теорема
В распределённой системе невозможно одновременно гарантировать все три свойства. При network partition нужно выбирать между Consistency и Availability.
Consistency
Все узлы видят одинаковые данные в один момент времени
Availability
Каждый запрос получает ответ (успех или ошибка)
Partition Tolerance
Система работает при разрыве связи между узлами
На практике: CP-системы (HBase, MongoDB) жертвуют доступностью ради консистентности. AP-системы (Cassandra, DynamoDB) жертвуют строгой консистентностью ради доступности.
Подробнее
PACELC теорема
Расширение CAP для нормального режима работы системы.
PACELC теорема
Расширение CAP: даже без partition (в нормальном режиме) приходится выбирать между Latency и Consistency.
Partition → Availability vs Consistency, Else → Latency vs Consistency
PA/EL системы
При partition выбирают Availability, в норме — низкую Latency
PC/EC системы
При partition и в норме выбирают Consistency (строгая консистентность)
Практический смысл: PACELC помогает понять trade-offs в нормальном режиме работы. Синхронная репликация даёт консистентность, но увеличивает latency. Асинхронная — снижает latency, но данные могут быть stale.
Stateless архитектура
Stateless compute — простейший множитель масштабируемости. Когда инстансы заменяемы, всё становится проще:
Autoscaling работает
Можно добавлять/убирать инстансы
Деплои безопаснее
Rolling update без потери состояния
Быстрое восстановление
Падение ноды не критично
Важно: Stateless не означает "без in-memory оптимизаций". Это значит, что система не зависит от памяти для корректности. Сессии, workflow state и критичные данные должны храниться отдельно (Redis, DB).
Связанная глава
Репликация и шардинг
Детальный разбор топологий, ребалансировки и консистентности.
Паттерны масштабирования баз данных
Шардинг (Partitioning)
Горизонтальное разделение данных по нескольким серверам. Улучшает масштабируемость записи.
Репликация
Копирование данных на несколько серверов. Улучшает масштабируемость чтения и отказоустойчивость.
Связанная глава
Стратегии кэширования
Cache-Aside, Write-Through, Write-Back и практические trade-offs.
Кэширование
Многоуровневое кэширование — один из самых эффективных способов снижения latency и нагрузки на backend.
CDN
~5ms
Redis/Memcached
~1-5ms
Local Cache
~0.1ms
Database
~10-100ms
Cache-Aside (Lazy Loading)
Приложение читает из кэша, при miss — идёт в DB и записывает в кэш
Write-Through
Запись идёт сначала в кэш, затем кэш записывает в DB
Write-Behind (Write-Back)
Кэш накапливает записи и периодически сбрасывает в DB
Refresh-Ahead
Проактивное обновление "горячих" данных до истечения TTL
Latency vs Throughput
Два главных измерения производительности. Latency отвечает за ощущение скорости для пользователя, throughput — за объём работы, который система умеет проглотить.
Latency
Время от запроса до ответа. Главный показатель — p95/p99, а не среднее.
- Метрики: p50/p95/p99, tail latency
- Болезни: очереди, синхронные блокировки, сетевые hops
Throughput
Количество операций в секунду (RPS/QPS, events/sec). Ключевой KPI для batch и фоновой обработки.
- Метрики: RPS, ops/sec, bytes/sec
- Болезни: блокирующий I/O, недостаток параллелизма
Latency first
Кэширование, предвычисления, короткий критический путь, параллелизм.
Throughput first
Батчинг, очереди, bulk I/O, асинхронная обработка, горизонтальный скейлинг.
Tradeoff
При высокой утилизации latency растёт нелинейно. Контролируйте очереди и вводите backpressure.
Rule of thumb: для интерактивных UX — минимизируйте latency, для фоновых пайплайнов — оптимизируйте throughput.
Связанная глава
Асинхронная обработка и Event-Driven Architecture
Как проектировать очереди, события и delivery semantics.
Асинхронная обработка
Message Queues
Отделение тяжёлой обработки от основного потока запросов.
Event-Driven Architecture
Сервисы общаются через события. Слабая связанность, независимое масштабирование.
CQRS (Command Query Responsibility Segregation)
Разделение моделей чтения и записи для независимой оптимизации каждой части системы.
Write Model (Commands)
Оптимизирован под транзакции и валидацию. Нормализованные данные.
Read Model (Queries)
Оптимизирован под быстрое чтение. Денормализованные, предагрегированные данные.
Полезно когда read/write нагрузки
сильно различаются по объёму
Связанная глава
Паттерны отказоустойчивости
Circuit Breaker, Bulkhead, Retry и практики graceful degradation.
Паттерны устойчивости (Resilience)
Circuit Breaker
Предотвращение каскадных сбоев. При достижении порога ошибок — разрывает соединение с "больным" сервисом.
Backpressure
Способность системы отклонять избыточную нагрузку до того, как перегрузка приведёт к отказу.
- Bounded queues
- Admission control (HTTP 429)
- Degraded responses
Retries + Idempotency
Retries неизбежны в распределённых системах. Idempotency гарантирует, что повторные запросы безопасны.
Bulkhead
Изоляция ресурсов для предотвращения распространения сбоев. Отдельные пулы потоков/соединений для критичных функций.
Как водонепроницаемые отсеки на корабле 🚢
Фундамент
HTTP протокол
L7 балансировка использует HTTP и правила маршрутизации.
Связанная глава
Балансировка трафика
Round Robin, Least Connections и Consistent Hashing на практике.
Load Balancing
Алгоритмы
Уровни
TCP/UDP, быстрый, простой
HTTP, роутинг по URL/headers
Geo-routing, failover
Сводная таблица паттернов
| Паттерн | Преимущество | Tradeoff |
|---|---|---|
| Horizontal Scaling | Эластичный рост | Координация |
| Sharding | Write scalability | Операционная сложность |
| Replication | Read scalability | Consistency lag |
| Caching | Low latency | Stale data |
| Async processing | High throughput | Delayed results |
| Circuit Breaker | Fault isolation | State management |
| CQRS | Optimized paths | Consistency complexity |
Ключевые выводы
Stateless first — проектируйте вычислительные компоненты без состояния для простоты масштабирования
CAP awareness — понимайте tradeoffs между consistency и availability в вашей системе
Cache aggressively — многоуровневое кэширование драматически снижает latency
Async by default — отделяйте тяжёлую обработку от критического пути пользователя
Design for failure — Circuit Breakers, Retries, Bulkheads защищают от каскадных сбоев
Idempotency always — любая операция должна быть безопасна для повторного выполнения
