Модуль 1. Trade‑offs и принятие архитектурных решений
Цель модуля: научить студента не искать «идеальное решение», а осознанно выбирать компромиссы, фиксировать их в ADR, опираться на конкретные топологии Yandex Cloud и связывать выбор с целевыми метриками (Target SLO).
Стадия роста проекта: Идея / прототип. Проект ещё не написан. Команда спорит о стеке, архитектуре, БД. И первое, что ломается — не код, а решение. Без ADR и Target SLO любой выбор — это мнение, не аргумент.
Перед началом: вводный модуль, специальных знаний не требуется Инструменты: — (теория + 2 сценария) Трудоёмкость: ~4 ч (теория 2.5 ч · сценарии 1.5 ч)
🔥 Два звонка в один день
Утро понедельника. Два звонка подряд — и оба требуют решения «прямо сейчас».
10:00. PM финтех-модуля: p99 записи — 450 мс, конверсия падает. «Сделай быстрее». CTO добавляет: «Но если появится двойное списание — это репутация и штрафы. Выбери, что жертвуем: скорость или консистентность. И дай цифры». Ты открываешь черновик ADR: вариант A (CP, синхронная репликация) — RPO = 0, но p99 вырастет до 600 мс, конверсия −12%. Вариант B (AP, асинхронная) — p99 450 мс, но RPO > 0, риск двойного списания. Бизнес: «Двойное списание недопустимо». Решение: CP, Target SLO p99 ≤ 600 мс, RTO < 1 мин.
11:30. PM ленты: «Хочу 100 000 RPS и мгновенную публикацию». Ты вспоминаешь «8 заблуждений» — «мгновенно» в распределённой системе не бывает. Предлагаешь Target SLO: 95% постов видны за 5 секунд, p99 ≤ 200 мс, eventual consistency в YDB. PM: «5 секунд — долго!». Ты: «Строгая консистентность → p99 800 мс → не держим 100k RPS → теряем пользователей». Решение: AP, eventual, Kafka + кэш.
Зрелый архитектор не обещает «идеально» — он показывает цену каждого «идеально» в цифрах. CAP, PACELC, ADR и Target SLO — это не абстракции, а инструменты для торга с бизнесом. Весь курс — про то, как смягчить последствия выбранного trade-off: CP потребует Saga и Outbox (Модули 3–4), AP — Circuit Breaker и кэш (Модуль 5).
📖 Теория: раскрытые термины и примеры
1.0. Что такое распределённая система и зачем она нужна
Распределённая система — это набор независимых узлов (серверов, процессов), которые работают совместно через сеть и представляются пользователю как единая система. Узлы могут быть физически распределены, работать под разными ОС и отказывать независимо друг от друга.
Почему не жить на одном сервере? Один сервер (vertical scaling) упирается в аппаратные пределы: максимальный CPU, RAM, диск. Рано или поздно ends — и дальше масштабироваться нельзя. Распределённые системы решают:
- Масштабируемость — горизонтальное масштабирование (добавь ещё узлов) не имеет теоретического предела, в отличие от вертикального (купи сервер побольше).
- Отказоустойчивость — если один узел падает, остальные продолжают работать. Один сервер = SPOF (Single Point of Failure).
- Производительность — параллельная обработка на N узлах в N раз быстрее (закон Амдала ставит реальный предел, но выигрыш значителен).
- География — сервер рядом с пользователем (CDN, Multi-Region) даёт меньшую latency.
- Объём данных — когда данные не помещаются на одном диске (TB → PB), без шардирования не обойтись.
Но: распределённые системы сложнее — сеть ненадёжна, узлы падают, данные расходятся. Весь этот курс — про то, как работать с этой сложностью, не теряя данные и рассудок.
1.0.1. Когда начинать строить распределённую систему
Не начинайте с микросервисов и Kubernetes. Монолит на одном сервере проще, дешевле и быстрее в разработке. Переход к распределённой архитектуре оправдан, когда:
| Сигнал | Что происходит | Что делать |
|---|---|---|
| БД — узкое место | p99 запросов растёт; CPU/IO на 100%; коннекты исчерпаны | Сначала: PgBouncer + read-реплики + кэш. Потом: партиционирование. В крайнем случае — шардирование (см. Модуль 9) |
| Вертикальное масштабирование упёрлось | Купили максимальный инстанс (128 vCPU, 1 TB RAM), а не хватает | Горизонтальное масштабирование — несколько инстансов за балансировщиком |
| Команда выросла | 10+ разработчиков наступают друг на друга в монолите | Разделение на сервисы (Conway's Law: архитектура = структура команды) |
| SLO не выполняется | Доступность < 99.9%; RTO > 1 часа | Multi-AZ, репликация, Circuit Breaker (Модуль 5) |
| География | Пользователи в других регионах жалуются на latency | Multi-Region или CDN |
Главный принцип: не «распределить потому что модно», а «распределить потому что есть измеримая проблема» (SLO, $, RTO). Каждое распределение добавляет сложность (сеть, консистентность, observability). Цена — время команды и риск багов.
1.0.2. С какими сложностями столкнулись инженеры: путь к CAP
В 1990-х системы начали активно распределяться (раньше — мейнфреймы). Инженеры столкнулись с новыми проблемами, которых не было на одном сервере:
- Сеть падает. Между дата-центрами рвётся кабель — узлы перестают видеть друг друга. Каждый думает: «другой умер, я — мастер». Получаем расщепление мозга (split-brain) и противоречивые данные.
- Latency не нулевая. Записать данные синхронно на 3 узла в разных зонах = +50-100 мс к каждому write. Бизнес говорит «медленно».
- Частичные сбои. Один из 5 узлов тормозит — вся цепочка ждёт его (head-of-line blocking). На одном сервере такой проблемы нет: либо работает, либо нет.
CAP-теорема (Brewer, 2000) появилась как ответ на эти проблемы на практике. Брюер сформулировал её из опыта построения инфраструктуры Inktomi (поисковик). Позже Гилберт и Линч (MIT, 2002) формально доказали.
Что значит P (Partition Tolerance)? P — это не выбор, а данность. В реальной сети разделения (partitions) происходят неизбежно: отказ свитча, падение зоны, сбой DNS. Поэтому архитектор не выбирает P — он выбирает, что пожертвовать при партишене: консистентность (C) или доступность (A).
Исторический контекст: до CAP инженеры пытались «сделать всё сразу» — и быстро, и надёжно, и доступно. CAP показала, что это невозможно фундаментально. Это не ограничение технологии, а закон математики (асинхронная сеть + отказы → нельзя гарантировать C и A одновременно).
1.1. Архитектурное решение: с чего начинается выбор
Архитектура — это не поиск «идеального» решения, а осознанный выбор компромиссов под конкретные требования. Любое решение фиксируется в ADR (Architecture Decision Record) и должно опираться на измеримые характеристики, а не на вкус автора.
Trade-off (компромисс). Архитектурный trade-off — это осознанный обмен: улучшая одну характеристику системы, мы сознательно ухудшаем другую. Нельзя одновременно максимизировать всё — надёжность, скорость, дешевизну, простоту; законы физики и математики (CAP, закон Литтла, Amdahl) ставят жёсткие границы. Поэтому работа архитектора — не найти «лучшее» решение, а решить, чем он готов пожертвовать ради чего, и зафиксировать это. Пример: синхронная репликация даёт надёжность (RPO = 0, потери данных нет), но увеличивает latency записи — это и есть trade-off Latency vs Consistency. Ключевой признак зрелого инженера — он называет цену решения в цифрах (Target SLO), а не утверждает «так лучше».
Functional vs Non-Functional Requirements (NFR). Функциональные требования описывают, что делает система (перевести деньги, показать ленту). NFR — насколько хорошо она это делает: производительность, надёжность, безопасность, стоимость. Именно NFR (а не функции) определяют архитектуру.
Базовый словарь метрик, которым мы пользуемся весь курс:
| Термин | Что значит | Пример |
|---|---|---|
| SLI (Service Level Indicator) | Сырая измеримая метрика качества | доля 200-х ответов = 200-х / всех запросов |
| SLO (Service Level Objective) | Целевое значение SLI, которое мы обязуемся держать | доступность ≥ 99.9% за 30 дней |
| SLA (Service Level Agreement) | Внешний договор с клиентом (часто строже SLO) | иначе — штраф/компенсация |
| Error Budget | Допустимый «запас ошибок» = 100% − SLO | при SLO 99.9% бюджет ≈ 43 мин даунтайма/мес |
Правило модуля: любое архитектурное решение сопровождается Target SLO — целевыми метриками, под которые мы проектируем. Без чисел «надёжно» и «быстро» — пустые слова.
Процентили вместо средних. «Среднее время ответа 50 мс» почти бесполезно: один запрос на 5 секунд не испортит среднее, но убьёт UX. Поэтому договоры считают перцентилями:
- p50 (медиана) — типичный запрос.
- p95 — 5% самых медленных запросов лежат выше этого значения.
- p99 — «хвост», 1% запросов; именно его чувствует пользователь при росте нагрузки.
SLO формулируют как «p99 latency записи ≤ 500 мс».
RTO и RPO — характеристики восстановления после сбоя:
- RTO (Recovery Time Objective) — сколько система может быть недоступна.
- RPO (Recovery Point Objective) — сколько данных допустимо потерять (зависит от частоты бэкапов/режима репликации).
Пример: финтех требует RTO < 1 мин и RPO = 0 (потеря платежа недопустима) → нужна синхронная репликация, асинхронная не подойдёт.
1.2. Заблуждения распределённых вычислений (Fallacies of Distributed Computing)
Классические 8 заблуждений (Peter Deutsch / Sun Microsystems) — это не абстрактные тезисы, а список того, что обязательно сломает систему, если не заложить защиту заранее.
- «Сеть надёжна» → нет. В Yandex Cloud межзональный трафик может теряться, latency между зонами A/B/C не нулевая. Следствие: любой HTTP-запрос между сервисами должен иметь таймаут и retry-стратегию.
- «Задержка нулевая» → нет. Даже внутри одной зоны есть latency, и каждый хоп её добавляет. Следствие: нельзя строить синхронные цепочки из 5+ сервисов без fallback и circuit breaker.
- «Пропускная способность бесконечна» → нет. У ALB, Managed PostgreSQL, Kafka есть лимиты (RPS, IOPS, число партиций). Следствие: проектируй backpressure (обратное давление) и rate limiting, иначе получишь 503 и рост latency.
- «Сеть безопасна» → нет. Трафик можно перехватить, запрос — подделать. Следствие: Edge-аутентификация (JWT), mTLS между сервисами, шифрование (подробно — Модуль 7).
- «Топология не меняется» → нет. Инстансы перезапускаются, поды умирают, зоны падают. Следствие: сервисы должны быть stateless, балансировка на L7/L4, graceful shutdown.
- «Есть один администратор» → нет. В распределённой системе много независимых владельцев и сред. Следствие: явные контракты (OpenAPI/proto), версионирование API, обратная совместимость.
- «Транспорт бесплатен» → нет. Межзональный трафик стоит денег, репликация БД тоже. Следствие: в ADR включай cost awareness (например, «жертвуем latency чтения, но экономим на трафике, читая из локальной реплики»).
- «Сеть однородна» → нет. Разное оборудование, версии протоколов, тайминги каналов. Следствие: не закладывайся на одинаковые характеристики связей — используй таймауты и ретраи с джиттером.
1.3. CAP и PACELC: что на самом деле означают буквы
Partition (P) — это не выбор, а данность. Разделение сети (узлы не могут общаться) в распределённой системе случается неизбежно: отказ свитча, падение зоны, сбой DNS. Поэтому «P» нельзя «не выбрать» — реально выбирать приходится между C и A во время партишена.
CAP и миф «2 из 3». Часто говорят «выбери любые две буквы из CAP». Это упрощение. Теорема (Brewer, формально доказана Gilbert и Lynch) звучит точнее: во время партишена нельзя одновременно дать и строгую консистентность (C), и 100% доступность (A) — чем-то придётся пожертвовать.
- CP — при партишене узел отклоняет запрос или ждёт, чтобы не отдать противоречивые данные (нет «расщепления мозга»). Примеры: HBase, MongoDB (по умолчанию), Managed PostgreSQL с синхронной репликацией.
- AP — узел отвечает устаревшими данными, но остаётся доступен; противоречия разрешаются позже. Примеры: Cassandra, DynamoDB, YDB в режиме eventual consistency.
«C» в CAP — это linearizability (см. 1.4), а не «C» из ACID. Путать их — частая и дорогая ошибка.
PACELC — CAP на каждый день. PACELC добавляет случай, когда партишена нет (Else): и тогда ты выбираешь между Latency и Consistency.
- If Partition: PA или PC.
- Else: EL или EC.
Тип системы — пара: Cassandra = PA/EL (всегда жертвует консистентностью ради доступности/latency); PostgreSQL с синхронной репликацией = PC/EC (жертвует доступностью/latency ради консистентности). Это объясняет, почему CP-системы «медленнее»: каждый write ждёт подтверждения от кворума.
CAP — это не ярлык на коробке, а спектр поведений, который можно тюнить (уровни кворума, синхронность реплики, таймауты).
1.4. Модели согласованности (Consistency Models)
«Сильная» и «eventual» согласованность — крайние точки шкалы. Между ними — набор моделей, и выбор зависит от того, какие аномалии готов терпеть бизнес.
| Модель | Гарантия | Где уместна |
|---|---|---|
| Linearizability (strong) | Все операции выглядят мгновенными в едином порядке; чтение всегда видит последнюю запись | Деньги, балансы, блокировки |
| Sequential consistency | Единый порядок операций, но без привязки к реальному времени | Редко в проде |
| Causal consistency | Сохраняется причинно-следственная связь (ответ виден только после причины) | Комментарии, треды |
| Read-your-writes (session) | Автор всегда видит собственные записи | Профиль пользователя |
| Monotonic reads | Нельзя «откатиться во времени» между чтениями | Лента (чтобы не «дёргалось») |
| Eventual consistency | Со временем данные сходятся, но временно могут расходиться | Лайки, счётчики, лента |
Связь с курсом: выбор модели согласованности определяет, понадобятся ли тебе Outbox/Saga (для strong) или разрешение конфликтов (для eventual) — это прямые мостики к Модулям 3–4.
1.5. ACID, BASE и уровни изоляции
ACID — гарантии локальной транзакции в одной БД:
- Atomicity (Атомарность) — все изменения выполняются целиком или ни одного (all-or-nothing).
- Consistency (Консистентность) — транзакция переводит БД из одного корректного состояния в другое (инварианты и ограничения не нарушаются).
- Isolation (Изоляция) — параллельные транзакции не мешают друг другу.
- Durability (Долговечность) — после COMMIT изменения переживают сбой (записаны на диск/WAL).
C из ACID ≠ C из CAP. ACID-C — про инварианты внутри одной БД (FK, NOT NULL, CHECK). CAP-C — про согласованность между узлами. БД может давать полноценные ACID-транзакции и при этом быть AP-системой (например, кластер с асинхронной репликацией: локально ACID, глобально eventual).
| Понятие | Что гарантирует | Где проявляется | Пример в стеке |
|---|---|---|---|
| ACID-транзакция | Атомарность и изолированность внутри одной БД | Один инстанс PostgreSQL | BEGIN ... COMMIT нескольких строк |
| Consistency в CAP | Глобальную согласованность между узлами | Распределённый кластер | Все реплики отвечают одинаково |
| Strong Consistency | Чтение всегда видит последнюю запись | Финтех, балансы | PostgreSQL с синхронной репликацией |
| Eventual Consistency | Чтение временно отстаёт | Лента, лайки | YDB / Cassandra, кэши |
Уровни изоляции (SQL Standard) — компромисс между корректностью и параллелизмом. Чем выше уровень, тем меньше аномалий, но ниже пропускная способность:
| Уровень | Защита от | Аномалия, которая остаётся |
|---|---|---|
| Read Uncommitted | — | грязное чтение (dirty read) |
| Read Committed (по умолч. в PostgreSQL) | грязное чтение | неповторяющееся чтение (non-repeatable read) |
| Repeatable Read | + неповторяющееся чтение | фантомы (phantom) |
| Serializable | + фантомы | — (самый строгий, но медленный) |
В Модулях 2 и 4 мы вернёмся к изоляции, когда будем бороться с гонками (SELECT ... FOR UPDATE) и идемпотентностью.
BASE — идеология AP-систем, антагонист ACID: Basically Available, Soft state, Eventually consistent. Система остаётся доступной ценой временной неконсистентности. Cassandra и DynamoDB построены по этому принципу.
1.6. Репликация, кворумы и консенсус: почему CP стоит дорого
Выбор CP/AP во многом определяется режимом репликации.
Синхронная репликация: мастер ждёт подтверждения от реплики (или кворума) до ответа клиенту. Данные не теряются (RPO = 0), но каждый write упирается в latency сети → выше задержка, а при падении реплики — простой.
Асинхронная репликация: мастер отвечает сразу, реплика «догоняет» позже. Быстро и доступно, но при падении мастера можно потерять последние неподтверждённые данные (RPO > 0).
Кворумы (quorum). В системе из N реплик запись подтверждается при достижении W узлов (write quorum), чтение — при R узлах (read quorum).
- Сильная консистентность:
R + W > N— запись и чтение гарантированно пересекаются хотя бы на одном актуальном узле. - Меньше latency / выше доступность:
R + W ≤ N— быстрее, но можно прочитать устаревшие данные.
Пример: N = 3. Вариант W=2, R=2 → сильная консистентность (2+2 > 3). Вариант W=1, R=1 → максимально быстро, но eventual.
Консенсус (Raft / Paxos). Чтобы кластер согласованно принимал решения (кто мастер, в каком порядке применять записи) и не давал «расщепления мозга», нужен алгоритм консенсуса. Он гарантирует CP, но платит за это: лишний раунд связи на запись (рост latency) и пауза при перевыборе лидера. Managed PostgreSQL и YDB скрывают эту сложность, но её цена отражается в метриках.
Вывод: CP «медленнее и дороже» не из-за плохой реализации, а фундаментально — сильная консистентность требует ожидания и кворумов. Это и есть trade-off Latency vs Consistency из PACELC.
1.7. Этот паттерн в архетипах
Trade-offs проявляются по-разному в четырёх архетипах проектов:
| Архетип | Главный trade-off | Типичный выбор CP/AP | Почему |
|---|---|---|---|
| Финтех (P2P) | Consistency vs Latency | CP, синхронная репликация | Двойное списание недопустимо; RPO = 0 |
| Git-хостинг | Latency vs Cost | CP для метаданных, AP для кэша деревьев | Refs должны быть консистентны; кэш может быть stale |
| Мессенджер | Availability vs Consistency | AP, eventual consistency | Сообщение может доставиться с задержкой; главное — доступность |
| Лента / чтение | Throughput vs Consistency | AP, кэш, eventual | 100k RPS на чтение; допустима задержка 5 сек |
1.8. Trade-offs: как переводить бизнес-требования в архитектуру
Каждое архитектурное решение — баланс по нескольким осям. Осознанный выбор = явная фиксация, чем мы жертвуем и ради чего.
Основные оси компромиссов:
- Consistency vs Availability (CAP): CP для платежей, AP для ленты.
- Latency vs Throughput: потоковая обработка (низкая задержка, меньше RPS) против пакетной (высокий throughput, выше задержка).
- Strong vs Eventual Consistency: strong для денег, eventual для лайков (см. 1.4).
- Cost vs Reliability (FinOps): Multi-AZ и реплики повышают надёжность, но стоят денег — каждая зона = отдельный счёт за инстансы и межзональный трафик.
- Coupling vs Autonomy: синхронные вызовы связывают сервисы (риск каскадных отказов), асинхронные (через брокер/Outbox) развязывают, но усложняют систему (eventual, идемпотентность).
- Simplicity vs Flexibility: монолит проще в эксплуатации, микросервисы гибче при масштабировании команд — но дороже в инфраструктуре.
Как решать (матрица решений): выписать критерии (из NFR/Target SLO), присвоить им веса, оценить каждую альтернативу по каждому критерию и выбрать максимум суммы «вес × оценка». Это превращает «мне кажется» в аргумент, который можно защитить в ADR.
Пример — два сценария курса:
- Финтех (P2P): приоритет — Consistency и RTO → CP, синхронная реплика, Managed PostgreSQL. Жертва: latency записи и доступность при failover.
- Лента новостей: приоритет — Throughput и Availability (100k RPS, допустима задержка) → AP, eventual, YDB/Cassandra. Жертва: временная неконсистентность и сложность разрешения конфликтов.
Любой trade-off из этого списка аукнется в следующих модулях: CP потребует Saga/Outbox (Модули 3–4), AP — разрешения конфликтов, везде нужны Resilience (Модуль 5) и Observability (Модуль 6).
1.9. Компромиссы (Trade-offs)
| Решение | Плюс | Минус | Когда выбирать |
|---|---|---|---|
| CP (синхронная репликация) | RPO = 0, strong consistency | latency записи выше; простой при failover | финтех, балансы |
| AP (асинхронная репликация) | низкая latency, доступность при сбоях | eventual consistency, риск потери данных | лента, лайки, search |
| ADR (формальный выбор) | аудит, воспроизводимость, защита на ревью | время на написание (~1 ч на ADR) | production-решения |
| «Просто сделаем» (без ADR) | быстро, не формализуется | нет аудита; «почему мы так решили?» через полгода | прототип, spike |
| Глубокий анализ (матрица критериев) | аргумент защищаем количественно | замедляет принятие решения | критичные выборы (БД, брокер) |
| Быстрый выбор (best practice) | не тратим время | может не подойти под NFR | некритичные части |
Вывод: зрелый инженер не ищет «лучшее» решение — он называет цену выбора в цифрах (RTO, SLO, $/мес) и фиксирует её в ADR. trade-off без цифр — это мнение, не аргумент.
🛠 Практические задания
Сценарий 1: Финтех (P2P‑переводы)
Требования: Недопустимо двойное списание. RTO < 1 мин.
Стек: Yandex Cloud (Managed PostgreSQL).
Сценарий 2: Лента новостей
Требования: Нагрузка 100 000 RPS на чтение. Допустима задержка до 5 сек.
Стек: Yandex Cloud (YDB или Cassandra).
📝 Шаблон ADR (Architecture Decision Record)
Заполняется студентом для выбранного сценария.
ADR: Выбор модели согласованности для [Финтех / Лента]
Контекст — Краткое описание сценария и бизнес‑критичности.
Цель — Что хотим достичь: доступность, низкая задержка, строгая консистентность и т.д.
Альтернативы
- Вариант А: [Топология 1] — Описание, плюсы, минусы, риски.
- Вариант Б: [Топология 2] — Описание, плюсы, минусы, риски.
Решение — Выбранный вариант и обоснование (обязательно со ссылкой на бизнес‑требование).
Последствия (Trade-offs)
- Target SLO: Ожидаемые целевые метрики (например, RTO < 1 мин, p99 latency записи ≤ 500 мс при синхронной репликации). На данном этапе оценочные бизнес-метрики, а не результаты замеров.
- Риски: Что может пойти не так (например, read-only режим при failover мастера).
- Компенсации: fallback, идемпотентность, повторные попытки, кэширование.
Связь с другими модулями — Как это решение повлияет на следующие модули (например, «потребуется Saga/Outbox»).
📐 Задание по визуализации (Mermaid)
Студент рисует диаграмму поведения при сетевом разделении (Partition) между Мастером и Репликой.
Обязательные элементы:
- API записи: как ведёт себя при Partition (отклоняет, переходит в read-only).
- API чтения: как ведёт себя + ОБЯЗАТЕЛЬНО покажи fallback-стратегию (например, если реплика недоступна, API читает последние успешные данные из Redis-кэша и помечает ответ заголовком
X-Data-Stale: true). - Таймауты и статусы ответов (200, 429, 503, 504).
Шаблон для ориентира:
🧩 Проверь себя
🤖 Инструкция для LLM (Coding Plan Assistant) — Режим Модуля 1
Используй этот промпт для старта работы со студентом:
Привет! Я начинаю Модуль 1 курса «Архитектура распределённых систем». Выступи в роли Наставника‑Архитектора.
Сначала проверь понимание: дай короткий ответ (1–2 предложения) — чем отличается Consistency в CAP от Consistency в ACID, и почему можно иметь ACID и при этом быть AP‑системой.
Затем выдай два сценария:
- Финтех (P2P) на Yandex Cloud (CP, RTO < 1 мин).
- Лента на Yandex Cloud (AP, p99 ≤ 50 мс, eventual consistency до 5 сек).
Для каждого сценария попроси студента:
- Предложить конкретную топологию и сервис Yandex Cloud (например, "PostgreSQL с синхронной репликацией" или "YDB в режиме eventual consistency").
- На основе выбранной топологии выбрать CP/AP и обосновать выбор в 2–3 предложениях.
- Указать 2 trade-offs с Target SLO (latency, RTO, error rate).
- Описать 1 риск и fallback-стратегию для его смягчения.
НЕ пиши ADR и НЕ рисуй Mermaid. Дождись ответа студента. После этого дай фидбек по чек‑листу ментора и укажи на слепые зоны (например, «ты не учёл межзональный трафик», «нет fallback-стратегии»).
📝 Чек‑лист ментора
Проверяй по этим пунктам:
-
Студент оперирует метриками корректно: SLI/SLO/SLA, перцентили (p99), RTO/RPO — а не словами «быстро/надёжно».
-
Студент не подменяет «строгую консистентность» на «ACID‑транзакцию в одной БД».
-
Различает модели согласованности (linearizability vs eventual и т.д.) и выбирает под бизнес.
-
Понимает цену CP: может объяснить кворумы (
R + W > N) и почему сильная консистентность дороже по latency. -
Для финтеха выбран CP, и студент может объяснить, почему AP здесь — фатальная ошибка.
-
В ADR есть конкретные последствия с целевыми метриками (Target SLO).
-
Указаны риски и способы их смягчения (fallback, идемпотентность, повторные попытки).
-
Mermaid‑диаграмма корректно показывает поведение API записи и чтения при Partition, включая таймауты, статусы ответов и явно отрисованный fallback (например, чтение из кэша).
-
Есть связь с будущими модулями: «этот выбор потребует Saga/Outbox» или «потребует разрешения конфликтов».
🔗 Мостики к следующим модулям
В конце ревью обязательно скажи студенту:
-
«Твой выбор CP для финтеха означает, что в Модуле 2 тебе придётся проектировать идемпотентность, потому что ретраи клиента неизбежны при сетевых сбоях. А в Модуле 3 — Outbox, потому что события не должны теряться при недоступности брокера.»
-
«Твой выбор AP для ленты означает, что в Модуле 5 нужно будет спроектировать механизмы разрешения конфликтов и eventual consistency, иначе пользователи будут видеть противоречивые данные.»
Если ты прошёл курс «Git Hosting: Serverless MVP», ты уже видел этот паттерн на упрощённом стеке: YDB Serverless (eventual consistency, ~0₽/мес) вместо Managed PostgreSQL. Паттерн тот же — инфраструктура разная. Здесь мы разбираем его на полном стеке, с глубиной и trade-offs.