fedorthinks

Экспресс-курс · No. 09

Масштабирование — это не «сделать всё быстрее», а найти ту одну часть, что прогибается под нагрузкой, и расширить её, потом следующую. Большинству систем этого нужно куда меньше, чем боятся их создатели; мастерство — знать, за чем тянуться и когда.

21 понятие · схема у каждого · шпаргалка в конце

§ 01

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

Scalability — масштабируемость

Маленькое кафе работает нормально, пока не подъезжает туристический автобус — и вдруг один бариста, одна касса, пара столиков не справляются. Масштабирование — это подготовка к автобусу.

Scalability (масштабируемость) — это способность системы держать рост: больше пользователей, запросов, данных, — оставаясь быстрой и живой. Это не про пик изобретательности; это про то, чтобы система не прогнулась, когда нагрузка умножится.

latencyload: users · requests · datascales: stays fastbuckles: one part can't keep up
Нагрузка растёт. Масштабируемая система остаётся быстрой; немасштабируемая в какой-то момент резко «ломается».
ConceptScalability· масштабируемость
Что это

Умение держать больше нагрузки и не становиться медленным или лежачим.

Как работает

Почти любая задача масштабирования сводится к одному: что-то становится той частью, что не поспевает.

Пример
Кафе, в которое внезапно приехал автобус туристов.
Связи

Растёт через Vertical и Horizontal Scaling; упирается в Bottleneck.

Vertical vs Horizontal — вверх или вширь

Чтобы везти больше, можно купить грузовик побольше — но он лишь до определённого размера — или купить больше грузовиков: предела почти нет, но теперь нужен диспетчер.

Есть ровно два способа нарастить мощность. Vertical scaling (вертикальное, scale up) — это машина побольше: больше CPU, больше RAM. Просто, но есть жёсткий потолок, и остаётся единая точка отказа. Horizontal scaling (горизонтальное, scale out) — это много машин, работающих вместе: предела почти нет, но нужна координация (балансировка, общее состояние). Вертикальное покупает время; горизонтальное — там, где живёт настоящий масштаб. Подробно — в главе 2.

Vertical — scale uphard ceiling4 CPU64 CPUbigger boxeasy · single point of failureHorizontal — scale outLoad balancerappappappappno real ceiling · needs coordination
Слева — одна коробка становится больше и упирается в потолок. Справа — коробок становится больше, а перед ними встаёт балансировщик.

Bottleneck — узкое место

Шоссе быстро ровно настолько, насколько быстр его самый узкий участок, — расширять все прочие полосы бессмысленно, пока не починишь горловину.

Bottleneck (узкое место) — это самая медленная часть системы, которая ограничивает всё остальное. Система быстра ровно настолько, насколько быстра она. Кидать ресурсы не туда — выброшенные деньги; работа в том, чтобы найти настоящее узкое место — базу, медленный сервис, сеть, — расширить его, потом найти следующее.

the bottleneckCDN10k rpsApp servers5k rpsDatabase800 rpsEmail API3k rpsthe whole system = its slowest part = 800 rpswiden it → the next bottleneck shows up
Цепочка держит столько, сколько держит её самое слабое звено. Здесь это база.
ConceptBottleneck· узкое место
Что это
Одна часть, которая не поспевает и тормозит весь поток.
Как работает

Расширил узкое место — появляется следующее. Масштабирование — это череда узких мест, а не один фикс.

Пример

CDN и серверы приложения держат тысячи запросов в секунду, а база — восемьсот. Добавлять серверы бесполезно.

Подвох

Легко «чинить» то, что просто казалось медленным, а не то, что им было.

Связи

Находится через Measure First; лечится ступенями Scaling Ladder.

Premature Scaling — преждевременное масштабирование

Ты не строишь шестиполосную автостраду к домику в лесу. Одна хорошая дорога увезёт всех, кто когда-либо приедет.

Premature scaling (преждевременное масштабирование) — это строить под нагрузку, которой у тебя нет. Один приличный сервер плюс база обслуживают поразительное число пользователей. Шардинг, микросервисы, навороченное кэширование до того, как появилась нагрузка, — это стоимость и сложность, которые тебе не нужны.

your real load1 server + DBholds it easilybuilt for millionscost + complexity you don't need
Реальная нагрузка, то, что держит один сервер с базой, и то, что построено «на вырост».
Anti-patternPremature Scaling· преждевременное масштабирование
Проблема

Сложность и деньги тратятся на нагрузку, которой нет и может не быть.

Пример

Шардированная база и микросервисы для приложения на сотню пользователей.

Лекарство

Сначала измерь; масштабируй то, что реально болит, когда оно реально болит.

Связи
Противоядие — Measure First и Scaling Ladder.

Карта: 21 понятие в семи группах

Карта метро: сначала видишь линии целиком, потом едешь по станциям.

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

FoundationsScalabilityBottleneckPremature scalingScale outVertical scalingHorizontal scalingStateless serverSpread trafficLoad balancerHealth checkRolling deployDo less workCacheCDNCache invalidationScale the dataDatabase bottleneckRead replicaShardingAsync & decoupleBackground jobLoad levelingDecouplingScale sanelyMeasure firstScaling ladderDesign for failure
Семь групп понятий — по ним идут главы 1–7.

Как читать каждое понятие

Паспорт: одинаковые поля у всех, поэтому их легко сравнивать.

У каждого понятия дальше одно и то же: английское название (запомни его — это термин, который ты встретишь в документации и на собеседованиях), образ из жизни, схема и карточка: проблема, идея, пример, цена, когда брать и связи с другими понятиями. В конце — шпаргалка со всеми терминами на одной странице.

Масштабирование — это не «сделать всё быстрее». Это найти узкое место, расширить его и повторить.

§ 02

Первые настоящие шаги вверх по лестнице масштабирования: перерасти одну большую коробку, потом сделать так, чтобы приложение могло крутиться сколькими угодно одинаковыми коробками.

Vertical Scaling — сначала коробка побольше

Когда кухня захлёбывается, первый фикс — плита побольше и больше столешницы, а не второй ресторан.

Vertical scaling (вертикальное масштабирование, scale up) — простейший ход: машина побольше. Оно не требует правок кода и быстро покупает реальный запас — часто его хватает надолго. Но есть жёсткий потолок (бесконечный сервер не купить), и эта одна коробка остаётся единой точкой отказа (single point of failure).

hard ceiling: no infinite server2 CPU4 GB8 CPU32 GB64 CPU512 GBstill one box =single pointof failureno code changes · buys time fast
Каждый шаг — более мощная машина. Но потолок близко, и машина всё равно одна.
PracticeVertical Scaling· вертикальное, scale up
Проблема
Сервер не тянет нагрузку: CPU или памяти не хватает.
Идея
Перейти на машину с бо́льшим числом CPU и RAM.
Пример
База переезжает с сервера на 8 ядер на сервер на 64 ядра.
Цена
Жёсткий потолок; одна коробка = единая точка отказа.
Когда брать

Первым. Используй его, чтобы выиграть время, а не как пункт назначения.

Связи

Первая ступень Scaling Ladder; следующий шаг — Horizontal Scaling.

Horizontal Scaling — много коробок, одна работа

Одна касса становится десятью — теперь десять клиентов обслуживаются разом, а если одна касса заклинит, остальные девять продолжают.

Horizontal scaling (горизонтальное масштабирование, scale out) — это много копий твоего приложения, между которыми делится работа. Предела почти нет, и оно переживает потерю любой одной машины. Подвох — координация: что-то должно распределять запросы (глава 3), а копии не должны каждая держать своё приватное состояние, — что и есть следующая, ключевая идея.

Load balancerapp #1same codeapp #2same codeapp #3downapp #4same codeapp #5same codemany identical copies · lose one, the others carry on
Пять одинаковых копий за балансировщиком. Одна упала — остальные четыре продолжают работать.
PracticeHorizontal Scaling· горизонтальное, scale out
Проблема
Одна машина, даже самая большая, упирается в потолок.
Идея
Запустить N одинаковых копий приложения и делить запросы между ними.
Пример
В «чёрную пятницу» магазин поднимает 20 копий вместо обычных 4.
Цена
Нужна координация: балансировщик и общее место для состояния.
Когда брать

Когда вертикального не хватает или нужна устойчивость к падению машин.

Связи
Работает только со Stateless Server; нужен Load Balancer.

Stateless Server — любая коробка обслужит любой запрос

Колл-центр, где любой оператор может принять любой звонок, потому что все детали клиента лежат в общей системе, а не в голове одного оператора.

Чтобы горизонтальное масштабирование работало, серверы приложения должны быть stateless (без состояния): они не держат в своей памяти ничего о пользователе между запросами. Данные сессии, загрузки, прогресс — всё это живёт где-то в общем месте (база, кэш, токен на руках у клиента). Тогда любой запрос может попасть на любой сервер, и добавление или потеря коробки ничего не меняют.

Requestapp serverremembers nothingapp serverremembers nothingapp serverremembers nothingany one of themShared statedatabase · cache · client token
Запрос может попасть на любой сервер: сами серверы ничего не помнят, всё состояние лежит в общем хранилище.
ConceptStateless Server· сервер без состояния
Проблема

Сервер помнит сессию у себя в памяти — пользователь «привязан» к нему, а при падении всё теряется.

Идея

Сервер ничего не хранит между запросами; состояние — в базе, кэше или токене клиента.

Пример
Корзина лежит в Redis, а не в памяти процесса; вход — через токен.
Цена
Каждый запрос ходит за состоянием в общее хранилище.
Когда брать

Всегда, если планируешь больше одного сервера. Безсостоятельность — это то, что делает «просто добавь серверов» реально рабочим.

Связи
Предпосылка для Horizontal Scaling и Rolling Deploy.

Вертикальное покупает время; горизонтальное покупает масштаб. И горизонтальное работает, только если серверы сами по себе ничего не помнят.

§ 03

Когда серверов много, что-то должно встать перед ними и решать, кто обработает каждый запрос. Это балансировщик нагрузки — регулировщик масштабированной системы.

Load Balancer — одна входная дверь, много серверов

Менеджер очереди в банке, направляющий каждого клиента к тому окошку, что свободно, — чтобы один кассир не был завален, пока другие сидят без дела.

Load balancer (балансировщик нагрузки) — Nginx, HAProxy, облачный балансировщик — это единая точка входа, которая распределяет входящие запросы по пулу серверов по простым правилам: round-robin (по кругу) или «шли наименее занятому» (least connections). Клиенты говорят с ним, а не с отдельными серверами, так что машины за ним можно добавлять и убирать незаметно.

clientclientclientLoad balancerNginx · HAProxy · cloudserver 1server 2server 3server 4one address for clients · round-robin or least-busy
Клиенты знают один адрес. Балансировщик раскидывает их запросы по серверам.
ToolLoad Balancer· балансировщик нагрузки
Проблема
Серверов много — кто решает, куда пойдёт каждый запрос?
Идея
Одна точка входа распределяет запросы по пулу серверов.
Пример
Nginx перед четырьмя копиями API шлёт запросы по кругу.
Цена
Ещё один компонент, который сам не должен стать единой точкой отказа.
Когда брать
Как только серверов больше одного.
Связи

Это то, что превращает кучу серверов в одну систему. Использует Health Check.

Health Check — не слать на мёртвых

Менеджер очереди замечает, что кассир отошёл, и просто перестаёт отправлять людей к тому окну — никто не ждёт у пустого стола.

Health check (проверка здоровья) — балансировщик постоянно проверяет, какие серверы здоровы, и обходит те, что нет. Упавшая или перегруженная коробка автоматически выводится из ротации, а трафик течёт к остальным. Так масштабированная система переживает смерть одной машины без того, чтобы пользователи это заметили.

Load balancerserver A200 OKserver Bno responseserver C200 OKGET /health ✗pulled from rotationtraffic only goes to servers that answer the check
Сервер B не ответил на проверку — балансировщик перестаёт слать ему трафик.
PracticeHealth Check· проверка здоровья
Проблема
Балансировщик шлёт запросы на сервер, который уже умер.
Идея

Регулярно опрашивать каждый сервер; не ответил — убрать из ротации, ожил — вернуть.

Пример

Каждые несколько секунд GET /health; нет ответа 200 — сервер выведен.

Цена
Плохо написанная проверка врёт: «здоров», когда база недоступна.
Связи
Часть Load Balancer; основа для failover и Design for Failure.

Rolling Deploy и Failover — бесплатные бонусы

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

Раз трафик течёт через балансировщик по взаимозаменяемым серверам, мощные вещи достаются почти даром: деплой без простоя (zero-downtime / rolling deploy) — обновляешь серверы по нескольку за раз; failover — когда один умирает, трафик уходит на остальные; и быстрый откат (rollback). Балансировщик плюс stateless-серверы — это становой хребет, что делает систему и масштабируемой, и устойчивой.

Load balancerv1servingv1servingv2deploying…v2servingupdate a few servers at a time; traffic routes around thema server dies → failover · bad release → route back to v1
Серверы обновляются по одному, остальные в это время обслуживают пользователей.
PracticeRolling Deploy· деплой без простоя + failover
Проблема
Выкатка новой версии означает «сайт недоступен».
Идея
Обновлять серверы по нескольку за раз, пока остальные держат трафик.
Пример

Из четырёх серверов два уже на v2, один обновляется, один ещё на v1 — пользователи ничего не замечают.

Цена
Какое-то время работают две версии сразу — они должны уживаться.
Связи
Требует Stateless Server, Load Balancer и Health Check.

Балансировщик превращает много серверов в один адрес — а умирающую машину в несобытие.

§ 04

Самая быстрая работа — та, которую ты не делаешь. Прежде чем масштабировать машины, делающие работу, сократи, сколько её вообще есть, — кэшами и CDN.

Cache — не считай один и тот же ответ дважды

Повар, который заготавливает популярный соус один раз утром, вместо того чтобы делать его с нуля под каждый отдельный заказ.

Cache (кэш) хранит результат дорогой работы — запрос к базе, посчитанную страницу, вызов API, — чтобы следующий запрос получил его мгновенно, а не переделывал. Быстрое хранилище в памяти (Redis, Memcached) перед базой может впитать основную массу чтений. Самая частая схема — cache-aside: сначала смотри в кэш, при промахе иди в базу и положи ответ в кэш.

AppCacheRedis · MemcachedDatabaseslow · expensive1 · check2 · miss → DB3 · storefor next timehit = answer from memory, the database is never touched
Cache-aside: проверить кэш → при промахе спросить базу → сохранить ответ на следующий раз.
PatternCache· кэш, cache-aside
Проблема
База снова и снова считает одни и те же ответы.
Идея
Запомнить результат в быстрой памяти и отдавать его повторно.
Пример
Карточка товара кэшируется в Redis — база её больше не пересчитывает.
Цена
Вторая копия правды, которая может протухнуть.
Когда брать

Часто перегруженной базе нужен именно кэш, а не больше серверов.

Связи

Требует продуманной Cache Invalidation; его родственник на краю сети — CDN.

CDN — обслуживай пользователей из ближнего

Глобальная сеть, которая держит одни и те же товары в локальных складах повсюду, — чтобы клиенты получали их из-за угла, а не везли через океан.

CDN (Content Delivery Network, сеть доставки контента) держит копии твоего статического контента — картинки, скрипты, видео, всё чаще и целые страницы — в дата-центрах по всему миру (edge), обслуживая каждого пользователя из ближайшего. Это режет задержку и снимает огромную нагрузку с твоего origin — твоих собственных серверов.

Originyour serversEdge · Europeimages · JS · pagesEdge · USimages · JS · pagesEdge · Asiaimages · JS · pagesEdge · LatAmimages · JS · pageseach user is served by the nearest copy
Origin раздаёт копии по edge-узлам в разных регионах; пользователь получает ответ из ближайшего.
ToolCDN· Content Delivery Network
Проблема
Пользователь на другом конце света ждёт, пока байты пересекут океан.
Идея
Хранить копии статики в узлах рядом с пользователями.
Пример
Картинки сайта отдаются из узла во Франкфурте, а не с сервера в США.
Цена
Та же проблема кэша: копии надо обновлять при изменениях.
Когда брать

Для всего глобального и статического — CDN делает тяжёлую работу ещё до того, как твои серверы увидят запрос.

Связи
Это Cache на краю сети; страдает от той же Cache Invalidation.

Cache Invalidation — самое сложное

Календарь на холодильнике быстрее, чем проверять телефон, — пока кто-то не поменяет план в телефоне, и теперь холодильник врёт.

Кэш — это вторая копия правды, а копия может протухнуть (stale data). По-настоящему сложный вопрос не в том, чтобы добавить кэш, а в том, чтобы знать, когда его выбросить, — это и есть cache invalidation (инвалидация кэша). Кэшируй то, что читают намного чаще, чем пишут, ставь вменяемые сроки жизни (TTL) и всегда знай, что будет, когда кэш врёт.

DatabaseCacheprice = 10price = 12updateprice = 10price = 10stale!nobody told the cachethe cache keeps serving the old valuefix: delete on write · set a TTL (expiry)
Цена в базе поменялась, а кэш об этом не знает и продолжает отдавать старую.
ConceptCache Invalidation· инвалидация кэша
Проблема
Пользователи видят устаревшие данные из кэша.
Идея

Выбрасывать запись из кэша при изменении данных и/или ставить ей срок жизни (TTL).

Пример

При смене цены удаляем ключ product:42 из Redis; плюс TTL 5 минут на всякий случай.

Подвох

Забытый путь записи, который не чистит кэш, — и данные тихо врут часами.

Связи
Обратная сторона каждого Cache и CDN.

Самый дешёвый запрос — тот, который ты никогда не обслуживаешь. Кэшируй горячее, отдавай статику с edge и потей над инвалидацией.

§ 05

Рано или поздно база становится узким местом — это та одна часть, которую правда тяжело масштабировать, потому что она держит правду, общую для всех.

Database Bottleneck — база обычно стена

Десять касс, тянущихся в одну-единственную кладовку, — кассиры масштабируются, но одна дверь кладовки становится затором.

Можно крутить сотню stateless-серверов приложения, но они обычно делят одну базу — и она становится пределом. В отличие от серверов приложения, её нельзя просто клонировать, потому что каждая копия должна сходиться в данных. Поэтому масштабирование базы — самая тяжёлая, самая аккуратная часть масштабирования системы.

appappappappappDatabaseone shared truthapp servers clone easily · the database can't
Серверы приложения множатся легко, но все они упираются в одну общую базу.
ConceptDatabase Bottleneck· база как узкое место
Что это
Общая база, в которую упираются все серверы приложения.
Почему
Копии базы должны сходиться в данных — их нельзя просто клонировать.
Что делать

Откладывать кэшированием как можно дольше; потом — реплики; шардинг — в последнюю очередь.

Связи
Лечится через Cache, Read Replica, Sharding.

Read Replica — копии для чтения

Раздать фотокопии справочника, чтобы многие читали разом, пока единственный мастер-экземпляр — единственный, в котором кто-либо пишет.

Большинство приложений читают намного больше, чем пишут. Read replicas (реплики для чтения) — это копии базы, обслуживающие запросы на чтение, размазывающие эту нагрузку по машинам, пока записи всё ещё идут в один primary. Это первый и самый лёгкий шаг масштабирования базы — но копии чуть отстают (replication lag), так что только что записанное значение может не появиться на реплике мгновенно.

AppPrimaryall writesRead replicaRead replicaRead replicawritesreadsreplicas copy the primary — with a small lag
Записи идут только в primary, чтения раскиданы по репликам. Реплики догоняют primary с небольшой задержкой.
PatternRead Replica· реплика для чтения
Проблема
База тонет в запросах на чтение.
Идея
Копии базы отвечают на чтения; все записи — в один primary.
Пример
Ленту и поиск читают с трёх реплик, а заказы пишутся в primary.
Цена

Replication lag: пользователь сохранил профиль, обновил страницу — а там ещё старое.

Когда брать
Когда нагрузка в основном чтения и кэша уже не хватает.
Связи

Следующая ступень после Cache; если не хватает записей — Sharding.

Sharding — дели записи

Один переполненный гроссбух становится несколькими — A–M в одной книге, N–Z в другой, — чтобы два клерка писали разом, не дерясь за одну страницу.

Когда даже записи перерастают одну машину, ты шардируешь (sharding): делишь данные по нескольким базам по какому-то ключу — shard key, — чтобы каждая держала свой кусок. Это открывает огромный масштаб, но правда тяжело — межшардовые запросы становятся болезненными, а ключ шардирования — почти необратимый выбор.

Shard routershard key = customer nameShard 1A – HShard 2I – PShard 3Q – Zeach shard holds a slice — writes are split toocross-shard queries hurt · the key is hard to change
Роутер смотрит на ключ и отправляет данные в нужный шард. Каждый шард держит свой кусок.
PatternSharding· шардирование, горизонтальное партиционирование
Проблема
Записей столько, что одна машина-primary их не вывозит.
Идея
Разрезать данные по ключу на несколько независимых баз.
Пример
Клиенты A–H в шарде 1, I–P в шарде 2, Q–Z в шарде 3.
Цена
Запросы через несколько шардов болезненны; ключ почти нельзя поменять.
Когда брать

Это глубокий конец; достигай его последним, когда реплик и кэширования правда не хватает.

Связи
Последняя ступень Scaling Ladder; после Read Replica.

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

§ 06

Не всякая работа должна происходить, пока пользователь ждёт. Унести медленную работу с пути запроса и поставить буферы между частями — вот как система остаётся быстрой и впитывает всплески.

Background Job — унеси медленную работу с пути запроса

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

Когда запрос запускает что-то медленное — отправку письма, генерацию отчёта, обработку загрузки, — не заставляй пользователя этого ждать. Передай это в фоновую очередь и сразу возвращайся; worker (обработчик) сделает медленную часть позже. Это background job (фоновая задача). Страница остаётся шустрой, а тяжёлая работа идёт в стороне. (Идея из курсов про протоколы и архитектуру.)

UserAppQueueWorkerinstant replyenqueueSend emailslow · secondsthe user waits only for the fast partthe slow work happens off to the side
Приложение кладёт задачу в очередь и сразу отвечает. Письмо отправит worker — позже и в стороне.
PatternBackground Job· фоновая задача, async processing
Проблема
Пользователь ждёт секунды, пока сервер делает медленную работу.
Идея
Положить задачу в очередь, ответить сразу, а работу сделает worker.
Пример

После регистрации письмо «добро пожаловать» отправляется в фоне — страница открывается сразу.

Цена
Результат приходит не сразу; нужна очередь и обработка ошибок worker'а.
Когда брать
Для всего, что пользователю не нужно увидеть прямо сейчас.
Связи
Та же очередь даёт Load Leveling и Decoupling.

Load Leveling — очереди впитывают всплески

Водохранилище между разлившейся рекой и городом — паводок наполняет водохранилище, а не топит улицы, и стекает ровным темпом.

Очередь — это ещё и буфер. Этот приём называют queue-based load leveling (выравнивание нагрузки очередью). Когда трафик внезапно подскакивает — запуск, вирусный момент, — работа копится в очереди, а воркеры разгребают её в своём темпе, вместо того чтобы поток обрушил систему. Без этого буфера всплеск, что приходит быстрее, чем ты успеваешь обработать, кладёт всё.

spiky trafficqueue = bufferworkers: steady pacea spike becomes a backlog, not a crash
Слева — рваный входящий трафик, в середине — очередь копит задачи, справа — воркеры работают ровно.
PatternLoad Leveling· queue-based load leveling
Проблема
Всплеск трафика быстрее, чем система успевает обработать.
Идея
Очередь копит работу, воркеры разбирают её с постоянной скоростью.
Пример

В момент запуска приходит в десять раз больше заказов — они ждут в очереди, а не роняют сервис.

Цена
Во время всплеска работа делается с задержкой; очередь надо мониторить.
Связи

Очередь превращает смертельный всплеск в управляемый бэклог. Родственник Background Job.

Decoupling — одна медленная часть не топит остальные

Водонепроницаемые отсеки на корабле — если один затопит, переборки держат остальные сухими, а корабль на плаву.

Decoupling (развязка) — когда сервисы говорят через очереди и события, а не прямыми блокирующими вызовами, медленный или упавший компонент не замораживает всех, кто его ждёт. Заказ всё равно принимается, даже если сервис писем лежит, — он просто догонит позже. Развязка — это то, что позволяет большой системе деградировать изящно под стрессом, а не падать целиком разом.

Direct, blocking callOrder serviceEmail servicedown✗ order fails tooThrough a queueOrder serviceQueueEmail servicedown✓ the order is taken · email catches up later
Сверху — прямой вызов: упал сервис писем, упал и заказ. Снизу — через очередь: заказ принят, письмо уйдёт позже.
ConceptDecoupling· развязка через очереди и события
Проблема
Один упавший сервис тянет за собой всех, кто его вызывает.
Идея
Общаться через очередь или события, а не ждать ответа напрямую.
Пример

Сервис заказов кладёт событие «заказ создан»; сервис писем заберёт, когда оживёт.

Цена
Сложнее проследить, что произошло; данные согласуются не мгновенно.
Связи

Основа Design for Failure; строится на тех же очередях, что Background Job.

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

§ 07

Хорошо масштабировать — это в основном сдержанность и порядок: измерь настоящее узкое место, поднимайся по дешёвым ступеням первыми и готовься к отказам, которые приносит больше машин.

Measure First — измеряй, прежде чем масштабировать

Врач делает анализы, прежде чем оперировать, — резать не тот орган, потому что ты угадал, не поможет никому.

Прежде чем что-то добавлять, найди настоящее узкое место метриками и профилированием (profiling) — это база, медленный запрос, сеть, CPU? Инженеры регулярно оптимизируют не то, потому что оно просто казалось медленным. Данные говорят, где система реально болит; масштабируй это и больше ничего. (Вот где наблюдаемость (observability) оправдывает себя.)

one request, 400 ms — where does the time go?app code40 msDB query280 msnetwork50 msrender30 msfix the long bar — not the one that merely felt slow
Разбор одного запроса: почти всё время уходит на запрос к базе. Чинить надо его.
PracticeMeasure First· сначала измерь, profiling
Проблема

Оптимизируют то, что «кажется» медленным, а узкое место в другом месте.

Идея
Метрики и профилирование показывают, куда реально уходит время.
Пример

Запрос идёт 400 мс, из них 280 мс — один запрос к базе. Значит, нужен индекс или кэш, а не больше серверов.

Цена
Нужна наблюдаемость: метрики, трейсы, логи.
Связи
Находит Bottleneck; защищает от Premature Scaling.

Scaling Ladder — поднимайся по дешёвой лестнице по порядку

Ты добавляешь утепление и герметизируешь окна, прежде чем покупать вторую печь, — дешёвые фиксы первыми.

Есть порядок, дешёвое и простое первым: коробка побольше, потом кэширование и CDN, потом stateless-серверы за балансировщиком с горизонтальным масштабированием, потом read-реплики, потом очереди для медленной работы — и лишь в самом конце шардинг. Каждая ступень — больше работы и больше сложности.

1 · Bigger box2 · Cache + CDN3 · Stateless + LB4 · Read replicas5 · Queues6 · Shardingcost ↑climb only as far as the load forces you
Шесть ступеней: чем выше, тем дороже и сложнее. Поднимайся, только когда нагрузка заставляет.
PracticeScaling Ladder· лестница масштабирования
Проблема
Хватаются сразу за самое мощное и сложное средство.
Идея

Идти по ступеням: коробка побольше → кэш и CDN → stateless + балансировщик → реплики → очереди → шардинг.

Пример

Сайт тормозит — сначала больше RAM и кэш; до шардинга дело может так и не дойти.

Когда брать

Всегда. Поднимайся ровно настолько, насколько вынуждает нагрузка.

Связи
Объединяет все понятия глав 2–6.

Design for Failure — больше машин, больше отказов

Одна лампочка редко перегорает за вечер; на стадионе из десяти тысяч несколько всегда не горят. На масштабе что-то всегда сломано.

По мере добавления машин вероятность, что что-то отказывает в любой момент, стремится к достоверности. Поэтому масштабирование и надёжность — один проект: избыточность (redundancy) — никакой единой точки отказа (single point of failure, SPOF); health-чеки и failover; и изящная деградация (graceful degradation), чтобы сломанная часть сбрасывала качество, а не убивала систему.

LBLB standbyappappdownappDB primaryDB standbyfailoverredundancy · no single point of failure · degrade, don't die
У каждого компонента есть запасной: второй балансировщик, несколько серверов, резервная база с переключением.
PracticeDesign for Failure· проектирование под отказ
Проблема
На масштабе какая-то машина ломается всегда.
Идея

Redundancy, health-чеки, failover и graceful degradation — отказ части не валит целое.

Пример

Упал сервис рекомендаций — магазин показывает страницу без блока «вам понравится», но продаёт.

Цена
Запасные машины стоят денег; переключения надо регулярно проверять.
Связи

Собирает Health Check, Rolling Deploy (failover) и Decoupling.

Как всё связано

Карта после поездки: теперь видно, какие станции на одной линии.

Понятия курса — не отдельные трюки, а одна цепочка. Измерь → найди узкое место → поднимись на нужную ступень лестницы. Горизонтальному масштабу нужны stateless-серверы и балансировщик; балансировщику — health-чеки; кэшу — инвалидация; очередям — выравнивание и развязка. А всё вместе служит одной цели: отказ одной части не должен убивать систему.

Measure firstBottleneckScaling ladderVerticalCache · CDNHorizontalRead replicaQueuesShardingInvalidationStatelessLoad balancerLoad levelingDecouplingRolling deployHealth checkDesign for failuremeasure → find the bottleneck → climb only the rungs you need
Главные связи между понятиями курса.
Прежде чем что-либо масштабировать
  • Измерил ли я, где настоящее узкое место, — а не угадал?
  • Есть ли ступень дешевле — коробка побольше, кэш, CDN — перед этой?
  • Stateless ли мои серверы приложения, чтобы я мог добавить ещё?
  • Нагрузка на базу — это чтения (реплики, кэш) или записи (тяжёлая дорога)?
  • Может ли медленная работа уйти за очередь?
  • Есть ли у меня вообще эта нагрузка — или я строю под будущее, которое может не прийти?
Признаки, что ты переусложнил
  • Шардинг базы, которую легко уместила бы одна коробка.
  • Микросервисы и очереди для приложения на сотню пользователей.
  • Масштабирование части, что не была узким местом, потому что оно казалось медленным.
  • Слой кэша настолько запутанный, что никто не уверен, когда он протух.
  • Постройка под миллионы пользователей, которых у тебя нет, и запуск, которого не было.
Признаки, что ты масштабировал хорошо
  • Ты масштабировал измеренное узкое место, и следующее теперь видно.
  • Серверы stateless; добавить или потерять один — несобытие.
  • Чтения закэшированы и реплицированы; база дышит.
  • Медленная работа идёт за очередями, и всплеск становится бэклогом, а не падением.
  • Нет единой точки отказа — любая одна машина может тихо умереть.
  • Ты поднялся ровно настолько по лестнице, насколько потребовала нагрузка.

Шпаргалка: все 21 понятие

Основы

Scalabilityмасштабируемость

Держать больше нагрузки и оставаться быстрым и живым.

Bottleneckузкое место

Самая медленная часть; она ограничивает всю систему.

Premature Scalingпреждевременное масштабирование

Строить под нагрузку, которой нет. Стоимость без пользы.

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

Vertical Scalingscale up

Машина побольше. Просто, но потолок и единая точка отказа.

Horizontal Scalingscale out

Много одинаковых копий. Почти без предела, нужна координация.

Stateless Serverсервер без состояния

Ничего не помнит между запросами — любой сервер обслужит любой запрос.

Распределить трафик

Load Balancerбалансировщик

Одна входная дверь, раздаёт запросы по серверам.

Health Checkпроверка здоровья

Мёртвые серверы автоматически выводятся из ротации.

Rolling Deployдеплой без простоя, failover

Обновлять по нескольку серверов; при падении трафик уходит на остальные.

Делать меньше работы

Cacheкэш, cache-aside

Запомнить дорогой ответ и отдавать повторно из памяти.

CDNContent Delivery Network

Копии статики рядом с пользователями по всему миру.

Cache Invalidationинвалидация кэша

Знать, когда выбросить копию: удаление при записи и TTL.

Масштабировать данные

Database Bottleneckбаза как стена

Одна общая база, которую нельзя просто клонировать.

Read Replicaреплика для чтения

Копии для чтений, записи в один primary. Есть небольшое отставание.

Shardingшардирование

Делить данные по ключу на несколько баз. Последнее средство.

Сглаживание и развязка

Background Jobфоновая задача

Медленная работа уходит в очередь, пользователь не ждёт.

Load Levelingвыравнивание очередью

Очередь превращает всплеск в бэклог, а не в падение.

Decouplingразвязка

Общение через очереди и события — упавшая часть не топит остальные.

Масштабировать здраво

Measure Firstсначала измерь

Метрики и профилирование показывают настоящее узкое место.

Scaling Ladderлестница масштабирования

Коробка → кэш/CDN → stateless + LB → реплики → очереди → шардинг.

Design for Failureпроектирование под отказ

Избыточность, failover и изящная деградация: на масштабе что-то всегда сломано.

Масштабируй узкое место, которое измерил, самым дешёвым инструментом, что его чинит, и считай, что на масштабе что-то всегда сломано. Всё остальное преждевременно.

Конец экспресс-курса · 7 глав · 21 понятие · измеряй, а не гадай

Дальше — глубина: снова «Designing Data-Intensive Applications», книги «System Design Interview» и инженерные блоги компаний, что масштабировались по-настоящему. Но держи ключевую мысль выше паттернов — система сильна ровно настолько, насколько прочна её слабейшая точка под нагрузкой. Найди эту точку, расширь её и не строй остальное, пока не придётся.