Схема системы собирается из небольшого словаря блоков — их меньше двадцати. Сильный дизайн отличается не знанием блоков (их знают все), а пониманием цены каждого: что блок покупает, чем за него платят и по какому числу из оценок он становится нужен. Эта статья — словарь с ценниками; глубокие разборы — по ссылкам в соответствующие разделы.
Стейтлес-сервисы и балансировка
Базовый блок: реплики без состояния за балансировщиком. Покупает горизонтальное масштабирование и переживание отказа реплики. Платится выносом состояния: сессии — в куки/токены, файлы — в object storage, всё остальное — в БД. Правило: сервис стейтлес, пока не доказано обратное — каждая крупица состояния в процессе лишает половины свойств этого блока. Механика — балансировка и endpoints в Kubernetes.
Кеширование
Покупает чтение за миллисекунды и разгрузку источника. Платится второй копией правды: инвалидация, устаревание, cache stampede, прогрев после рестарта. Появляется по числу: когда чтений на порядки больше записей и источник не успевает. Не появляется «на всякий случай» — кеш без измеренной необходимости это два источника багов по цене одного. Полный разбор — Caching Style Guide.
Репликация
Покупает переживание отказа узла БД и масштабирование чтения. Платится лагом реплики: read-after-write с реплики возвращает прошлое — и это свойство дизайна, которое надо обрабатывать (читать своё — с мастера). Запись репликация не масштабирует — это самое частое заблуждение дизайна. Разбор — PostgreSQL, MongoDB.
Партиционирование и шардинг
Покупает данные больше одного узла и масштабирование записи. Платится дорого: выбор ключа (равномерность против локальности запросов), кросс-шардовые запросы и транзакции, решардинг. Поэтому правило очередности: вертикальный рост → партиционирование → и только потом шардинг — по числам, а не по амбициям. Разбор — партиционирование в PG, шардинг Mongo, Distributed в ClickHouse.
Очереди и события
Покупают развязку во времени, сглаживание пиков, fan-out на много потребителей. Платятся eventual consistency, идемпотентностью потребителей (at-least-once неизбежен) и эксплуатацией брокера. На каждую стрелку схемы — вопрос sync или async; выбор инструмента — AMQP vs Kafka; надёжная публикация — outbox.
Поиск
Полнотекст, фасеты, релевантность — Elasticsearch или PG FTS, граница — отдельной развилкой. Платится вторым хранилищем с пайплайном синхронизации и лагом индексации. По числу: появляется от требований к качеству выдачи, не от слова «поиск» в требованиях — поиск по подстроке в админке блоком не является.
Аналитика
Агрегаты по миллиардам событий — ClickHouse; граница с PG — развилкой. Платится пайплайном (outbox → Kafka → консьюмер) и eventual-свежестью отчётов. Включает паттерн «события как данные»: append-only поток фактов как отдельная модель рядом с транзакционной.
Object storage и CDN
Файлы — S3-модель: неограниченный объём, presigned-доступ, lifecycle; граница с БД — развилкой. CDN сверху — когда контент читают многие и географически широко: покупает латентность у пользователя и разгрузку origin, платится инвалидацией («как обновить то, что закешировано на сотне узлов») и тем, что приватный контент требует подписанных ссылок.
Rate limiting и защита от перегрузки
Покупает выживание под пиком и защиту от злоупотреблений. Алгоритмы (token bucket, sliding window) — деталь; дизайн-решения — где (edge, шлюз, сервис) и по чему (пользователь, API-ключ, IP). Внутри системы парный блок — backpressure: очередь с лимитом честнее бесконечной, отказ быстрее таймаута (resilience).
Координация и согласованность
CAP в практическом пересказе: при сетевом разрыве выбирается либо доступность, либо согласованность — по операции, не по системе. Дизайн-вопрос каждой записи: что случится, если две реплики примут конфликтующие изменения? Ответы по нарастанию цены: единственный мастер (PG) → условные записи/версии (optimistic lock) → распределённые блокировки (дорого и хрупко — почти всегда есть способ проще, см. SKIP LOCKED). Консенсус (Raft) — блок, который берут готовым внутри инфраструктуры (Kafka, Keeper), а не строят.
Сводная таблица
| Блок | Покупает | Платится | Число-триггер |
|---|---|---|---|
| Стейтлес + балансировка | Масштаб, отказ реплики | Вынос состояния | Всегда, по умолчанию |
| Кеш | Быстрое чтение, разгрузка | Вторая правда, инвалидация | Чтений ≫ записей, источник не тянет |
| Репликация | Отказ узла, масштаб чтения | Лаг, read-after-write | Требование доступности БД |
| Шардинг | Масштаб записи и объёма | Ключ, кросс-шард, решардинг | Данные/запись не лезут в узел |
| Очереди | Развязка, пики, fan-out | Eventual, идемпотентность, брокер | Пики ≫ среднего; >1 потребителя |
| Поиск (ES) | Релевантность, фасеты | Второе хранилище, лаг | Качество выдачи — продукт |
| Аналитика (CH) | Агрегаты по млрд | Пайплайн, свежесть | Сотни млн событий, BI |
| Object storage | Безлимит файлов | Целостность БД+S3 | Файлы > 1 МБ или > ¼ БД |
| CDN | Латентность, разгрузка | Инвалидация, подписи | Географический разброс читателей |
| Rate limit | Выживание под пиком | Честные отказы 429 | Публичный API, пики |
Главное правило словаря: блок входит в схему по числу из шага оценок, и каждый блок в финальной схеме должен уметь ответить на вопрос «какое требование тебя сюда позвало».
Что почитать дальше
- Метод: шаг за шагом — процесс, в шаге 6 которого живёт этот словарь.
- Сквозной пример — блоки в действии на одной задаче.
- Архитектурный выбор — развилки внутри блоков: какое хранилище, какой брокер.
- Распределённые паттерны — связки блоков: saga, outbox, идемпотентность.