System Design

Основы масштабирования

Цели урока

  • Понять когда и зачем нужно масштабирование
  • Разобраться в вертикальном и горизонтальном масштабировании
  • Освоить концепцию Stateless vs Stateful
  • Понять CAP теорему и её практические следствия
  • Изучить основные паттерны масштабирования

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

  • Сбор требований (предыдущий урок)
  • Базовое понимание клиент-серверной архитектуры

2008 год, Twitter. Суперкубок, 50 000 твитов в секунду. Сервис падает. Пользователи видят «Fail Whale». Акции рекламодателей идут вниз. Именно тот день стал поворотным - команда начала строить архитектуру, которая через 5 лет выдерживала 143 000 твитов в секунду.

  • **Twitter 2013** - переход на горизонтальное масштабирование позволил выдержать нагрузку Суперкубка без единого Fail Whale
  • **Netflix** кешируют 99% запросов через EVCache (распределённый Memcached) - без кеша AWS bills выросли бы на порядок
  • **Amazon** разделил монолит на 100+ микросервисов в 2002 - каждый stateless, каждый масштабируется независимо
  • **Instagram** в 2012 году с 13 сотрудниками обслуживал 30 миллионов пользователей - PostgreSQL + Redis + Nginx + горизонтальное масштабирование

Закон Амдала и рождение горизонтального масштабирования

В 1967 году Джин Амдал (IBM) предсказал пределы параллельных вычислений. Его формула показала: последовательный код - bottleneck всей системы. В 2000-е, когда одиночные серверы достигли физического предела, индустрия массово перешла на горизонтальное масштабирование. Google в 2003 опубликовал GFS и MapReduce - первые публичные архитектуры для commodity hardware. Amazon перешёл на сервисную архитектуру по приказу Безоса в 2002. Netflix публично описал свою microservices трансформацию в 2009. Каждый следовал одной логике: не один производительный сервер - а много дешёвых.

Зачем масштабировать?

2008 год. Twitter запущен полтора года назад. Во время Супербоула сервис падает под нагрузкой. Все видят знаменитый "Fail Whale" - картинку с китом. 50 000 твитов в секунду. Один сервер. Конец истории. Тогда Twitter начал разбираться что такое **масштабирование**.

**Масштабирование** (Scaling) - способность системы обрабатывать растущую нагрузку. Не поддержать 100 пользователей, а перейти от 100 к 100 000 к 10 миллионам без переписывания с нуля.

**Когда нужно думать о масштабировании?**

  • **Latency растёт** - запросы выполняются медленнее
  • **CPU/Memory на пределе** - сервер загружен на 80-90%
  • **Ошибки под нагрузкой** - система падает в пиковые часы
  • **База данных - bottleneck** - запросы к БД занимают большую часть времени

Premature optimization is the root of all evil. Не масштабируй заранее - это добавляет сложность. Но проектируй так, чтобы масштабирование было возможным.

Когда стоит начинать масштабировать систему?

Вертикальное vs Горизонтальное

Есть два фундаментальных подхода к масштабированию: **вертикальное** (Scale Up) и **горизонтальное** (Scale Out). Разница не только техническая - она определяет всю архитектуру системы.

**Вертикальное масштабирование (Scale Up)** - увеличиваем производительность одного сервера: больше CPU, RAM, быстрее диск.

**Горизонтальное масштабирование (Scale Out)** - добавляем больше серверов, распределяем нагрузку между ними.

**Закон Амдала: математика против энтузиазма**

Не всё можно распараллелить. Закон Амдала - это холодный душ для архитекторов: последовательная часть кода ограничивает максимальное ускорение, сколько бы серверов ни добавить.

AWS EC2 instance types: от t3.micro (2 vCPU, 1 GB) до u-24tb1.metal (448 vCPU, 24 TB RAM). Вертикальное масштабирование имеет физический потолок - горизонтальное практически нет.

При проектировании главный вопрос: какая часть системы НЕ может быть распараллелена? Это bottleneck по Амдалу. База данных часто такой bottleneck - поэтому sharding и репликация так важны.

Stateless REST API. Какой тип масштабирования предпочтительнее?

Stateless vs Stateful

**Stateless** (без состояния) и **Stateful** (с состоянием) - ключевое разделение для масштабирования. Stateless сервисы масштабируются легко, Stateful - сложно. Это не рекомендация - это математика.

**Stateless сервис** - не хранит информацию между запросами. Каждый запрос содержит всё необходимое для обработки.

**Stateful сервис** - хранит состояние между запросами. Следующий запрос зависит от предыдущего.

**Как сделать Stateful -> Stateless?** Ключевая идея: выносим состояние во внешнее хранилище (Redis, Database), а серверы остаются без состояния.

  • **JWT tokens** - состояние в самом токене, сервер не хранит сессии
  • **Client-side state** - храним состояние в браузере (Redux, localStorage)
  • **Centralized cache** - Redis/Memcached для общего состояния
  • **Database** - все данные в БД, сервер только бизнес-логика

Stateful сервисы всё равно нужны: базы данных, очереди, кеши. Но их масштабируют отдельно и более аккуратно. Application layer должен быть stateless.

Веб-приложение хранит сессии пользователей в памяти сервера. Как сделать его stateless?

CAP теорема

**CAP теорема** (теорема Брюера) - фундаментальный закон распределённых систем. Невозможно одновременно гарантировать все три свойства: Consistency, Availability, Partition Tolerance. Это не рекомендация - это математически доказанная теорема.

В распределённой системе сетевые разделения (network partitions) **неизбежны**. Серверы в разных дата-центрах, сеть ненадёжна. Если система не переживает partition - она не распределённая. Поэтому реальный выбор: CP или AP.

**Уточнение: PACELC** - CAP говорит о поведении во время partition. Но что происходит в нормальном режиме? Расширение PACELC добавляет: Else (Latency vs Consistency). Даже без partition есть trade-off.

На практике большинство систем выбирают eventual consistency для большинства операций, и strong consistency только для критичных (платежи, инвентарь).

Проектируется система подсчёта лайков в социальной сети. Какой trade-off выбрать?

Паттерны масштабирования

Теория выше - фундамент. Теперь практика: пять паттернов, которые используются в реальных системах от стартапа до FAANG.

**1. Load Balancing** - распределяем запросы между серверами. Первый шаг горизонтального масштабирования.

**2. Database Replication** - копируем данные на несколько серверов. Увеличиваем read throughput и отказоустойчивость.

**3. Database Sharding** - разделяем данные на части (shards) по ключу. Масштабируем и чтение, и запись.

**4. Caching** - храним «горячие» данные в памяти. Снижаем нагрузку на БД и latency. Netflix кешируют метаданные фильмов в памяти - это 90% запросов без обращения к БД.

**5. Asynchronous Processing** - выносим тяжёлые операции в фоновую обработку через очереди.

Большинство реальных систем используют комбинацию паттернов. Load Balancing + Caching + Database Replication - базовый набор для любой нагруженной системы.

База данных - bottleneck. Читаем в 100 раз чаще, чем пишем. Какой паттерн применить первым?

Ключевые идеи

  • Вертикальное масштабирование (Scale Up) - увеличение производительности сервера, просто но имеет потолок
  • Горизонтальное (Scale Out) - добавление серверов, требует stateless архитектуры
  • Закон Амдала: 5% последовательного кода ограничивает ускорение до 20x даже при 100 серверах
  • CAP теорема: при network partition выбираем Consistency или Availability - третьего не дано
  • Паттерны: Load Balancing, Replication, Sharding, Caching, Async Processing - применяются в комбинации

Что дальше

Следующий урок: Основы баз данных - SQL vs NoSQL, ACID, репликация и шардинг на практике. Это детализация паттернов масштабирования для data layer.

  • CAP теорема (подробно) — Полный разбор CP vs AP с примерами Cassandra, etcd, Spanner
  • Базы данных: репликация и шардинг — Детализация паттернов масштабирования для data layer

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

  • Instagram с 13 сотрудниками обслуживал 30 миллионов пользователей. Какие именно решения по масштабированию позволили это сделать? Что было бы, если бы они выбрали CP вместо AP для лент?

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

  • ds-02 — CAP-теорема - фундамент выбора между CP и AP системами
  • bd-03 — Репликация и шардинг - детализация паттернов масштабирования для БД
  • cloud-03 — Auto-scaling в облаке строится поверх горизонтального масштабирования
  • devops-05 — Load balancing - первый шаг горизонтального масштабирования в prod
  • alg-01 — Big-O помогает найти bottleneck - последовательную часть по закону Амдала
  • se-08 — CQRS разделяет read/write path - та же логика что read replicas
  • dist-11-replication
Основы масштабирования

0

1

Войти