title: Системный дизайн — база знаний (числа, back-of-envelope, хранилища, паттерны, карта DDIA) source: подготовлено 2026-09-17, основание — TASK-45.1; источники — System Design Primer (Appendix + гайд), статья Яндекса habr 564132, DDIA Клеппмана, interactive latency (colin-scott, TASK-45.25), производственный опыт
База знаний по системному дизайну
Плотный справочник для архитектурной секции. Задача документа — чтобы на секции числа, названия паттернов и трейдоффы звучали из головы, без пауз. Формат: таблицы + короткие правила проговаривания. Как пользоваться: §1–2 выучить до автоматизма (это скелет back-of-envelope), §3–4 — критерии выбора, §5–11 — словарь паттернов с формулировками для доски, §12 — карта DDIA, §13 — карта инфографики «System Design Blueprint» с мини-блоками, которых не было в §1–12.
1. Числа
1.1 Степени двойки
| Степень | Точное значение | Приближение | Название |
|---|---|---|---|
| 2^10 | 1 024 | ~1 тысяча | 1 KiB |
| 2^20 | 1 048 576 | ~1 миллион | 1 MiB |
| 2^30 | ~1.07 × 10^9 | ~1 миллиард | 1 GiB |
| 2^40 | ~1.1 × 10^12 | ~1 триллион | 1 TiB |
| 2^50 | ~1.13 × 10^15 | ~1 квадриллион | 1 PiB |
| 2^60 | ~1.15 × 10^18 | ~1 квинтиллион | 1 EiB |
Размеры типовых сущностей (нужно для оценки storage):
| Сущность | Размер |
|---|---|
| Символ ASCII / байт UTF-8 (латиница) | 1 байт |
| Int / float | 4 байта |
| Long / double / Unix-timestamp (int64) | 8 байт |
| IPv4-адрес | 4 байта |
| UUID | 16 байт |
| IPv6-адрес | 16 байт |
| SHA-256 (хеш) | 32 байта |
| Короткая строка / URL | ~50–500 байт |
| Запись в БД среднего размера | ~100 байт – 1 КиБ |
| Страница HTML (сжатая) | ~50–100 КиБ |
| Фото (сжатое) | ~0.1–5 МиБ |
| Минута видео 480p / 1080p | ~10 МиБ / ~50–100 МиБ |
1.2 Latency numbers every programmer should know
| Действие | Время | В человекообразных единицах (1 нс = 1 с) |
|---|---|---|
| L1 cache reference | 0.5 нс | 1 с |
| Branch mispredict | 5 нс | 5 с |
| L2 cache reference | 7 нс | 7 с |
| Захват/освобождение mutex | 25 нс | 25 с |
| Обращение в RAM | 100 нс | 2 мин |
| Сжатие 1 КиБ (snappy/zstd) | ~3–10 мкс | ~час |
| Отправить 2 КиБ по 1 Gbps | 20 мкс | 5.5 ч |
| Чтение 1 МиБ последовательно из RAM | 250 мкс | ~3 суток |
| Round-trip внутри дата-центра | 0.5 мс | ~6 суток |
| Чтение 1 МиБ последовательно с SSD (NVMe) | 50 мкс – 1 мс | до 12 суток |
| Random read 4 КиБ с SSD | ~150 мкс | ~2 суток |
| Disk seek (HDD) | 10 мс | 4 месяца |
| Чтение 1 МиБ последовательно с HDD | 30 мс | 1 год |
| Round-trip через океан (CA ↔ Европа) | ~150 мс | 4.8 года |
Производные метрики (та же таблица «на поток»):
| Канал | Скорость последовательного чтения |
|---|---|
| RAM | ~4 ГиБ/с |
| SSD | ~1 ГиБ/с (NVMe — до 3–7 ГиБ/с) |
| HDD | ~30–100 МиБ/с |
| Сеть 1 Gbps | ~100–125 МиБ/с |
| Сеть 10 Gbps | ~1 ГиБ/с |
| Round-trip в ДЦ | ~2 000 RT/с — сетевые хопы «не бесплатные» |
| Свет вокруг Земли | ~5–7 оборотов/с — «скорость света» в распределённых системах это ~150 мс до другого континента |
Мнемоники: - Лестница ×1000: нс → мкс → мс → с. RAM — нс, SSD — мкс, HDD и сеть до другого ДЦ — мс, океан — сотни мс. - Каждый следующий уровень быстрее предыдущего в ~10–1000 раз; RAM быстрее SSD в ~100–1000 раз, SSD быстрее HDD-seek в ~100 раз. - «Память — это бесплатно, диск — это дорого, сеть через океан — это вечность»: отсюда все паттерны (кэш, батчинг, locality). - Избегать: random reads на HDD (10 мс seek), синхронных вызовов через океан в горячем пути, «одна лишняя цифра в латентности = другой дизайн». - Порог человеческого восприятия — ~100 мс: лаг меньше ~100 мс человек не замечает (источник 4, habr 516604). Отсюда SLO 150 мс у эталона Яндекса — «на грани комфорта», а round-trip через океан (~150 мс) сам съедает весь бюджет ответа.
Происхождение чисел: тренды железа (материал 21, colin-scott — интерактивная таблица «числа по годам»):
- CPU-числа — это такты: L1 = 3, branch mispredict = 10, L2 = 13, mutex = 50, сжатие 1 КиБ = 6 000 тактов; при 3 ГГц (0.33 нс/такт) → 1 / 3 / 4 / 17 нс / 2 мкс. На секции называть порядок, не десятые доли (CPU-числа плавают в разы от машины к машине, порядок — стабилен).
- Стена частот — 2005 год: герцы удваивались каждые 2 года до ~2005, дальше замерли на ~3 ГГц; расти продолжили ядра, не герцы. Однопоточная производительность исчерпана — горизонтальное масштабирование и конкурентность не выбор, а следствие.
- Полы латентности не двигаются 20+ лет: RAM 100 нс (шина даже деградирует с 2000), RT в ДЦ 0.5 мс, океан 150 мс — скорость света. Полосы при этом удваиваются: NIC ×2/2 года, DRAM и SSD ×2/3 года, HDD ×2/5 лет, HDD-seek — всего /2 за 10 лет (самый медленный тренд).
- Фраза для доски: «полоса дешевеет, латентность — нет» → батчить, пайплайнить, параллелить, меньше round trip'ов. Одним предложением объясняет пайплайны в протоколах, батчи в Kafka, мультиплексирование HTTP/2.
- Цветовая лестница ×100 (визуальная мнемоника источника): такты/нс → RAM/100 нс → сеть и SSD в ДЦ/10 мкс → диски и океан/мс — перепутать классы сложно: мьютекс не бывает «зелёным», RT в ДЦ — «синим».
- Ориентир свежести: обновление таблицы 2018 (Jeff Dean) — сжатие 1 КиБ 10 → 2 мкс, SSD random read 150 → 16 мкс; на секции безопаснее консервативные значения канона. Конспект и пересчёт тренд-модели →
materials/lsd-interactive-latency.md.
1.3 Календарные константы
| Константа | Значение | Округление для доски |
|---|---|---|
| 1 час | 3 600 с | 3.6 × 10^3 |
| 1 сутки | 86 400 с | ~100 тыс. с (10^5) |
| 1 месяц (30 дней) | 2 592 000 с | ~2.5 млн с |
| 1 год | 31 536 000 с | ~30 млн с (3 × 10^7) |
| 100 лет | ~3.15 млрд с | ~3 × 10^9 |
Availability в минутах простоя: 99 % = 3.65 дня/год; 99.9 % («три девятки») = 8.7 ч/год; 99.99 % = 52 мин/год; 99.999 % = 5 мин/год (доп. Alex Xu, гл. 2: простой = (100 − SLA)% × год).
2. Back-of-envelope estimation
2.1 Метод (порядок вопросов себе)
- Масштаб пользователей: DAU / MAU, пик одновременных.
- RPS:
QPS_avg = DAU × запросов/сутки / 86 400;QPS_peak ≈ 2–3 × QPS_avg(утро/вечер, релизы). Reads обычно ≥ writes в 10–100 раз; запись чаще всего и есть узкое место по консистентности. - Storage:
записей/с × размер × секунд/год × retention × фактор репликации+ индексы (×2 от сырых данных — хорошая прикидка). - Bandwidth:
чтение = read QPS × размер объекта,запись = write QPS × размер. Сравнить с 1/10 Gbps NIC и решить: нужен ли CDN / сжатие. - Память кэша: правило 80/20 — кэшируем горячие 20 %;
память = 0.2 × DAU × запросов/сутки × размер объекта. - Серверы: типовое приложение-сервис держит ~1–10 тыс. RPS на ноду (зависит от работы: CPU-bound vs IO-bound); БД — лучше не считать «одна нода потянет», а сразу делить роли.
Правило разговора: назвать допущение → формулу → число → вывод («это терабайты, влезает в одну ноду, значит узкое место не storage, а RPS на чтение → кэш/KV-зеркало»).
2.2 Пример 1: storage (URL shortener)
Дано: 100 млн новых ссылок/месяц, retention 10 лет, запись ~500 байт.
- Записи:
100M × 12 мес × 10 лет = 12 млрд записей. - Сырые данные:
12G × 500 Б = 6 ТБ; с индексами и оверхедом ×2 → ~12 ТБ. - Вывод: 12 ТБ — это одна-две ноды с дисками; storage не узкое место. Значит дизайн крутится вокруг чтения (см. classic-designs.md: 500k RPS → KV-зеркало + кэш).
2.3 Пример 2: RPS (лента новостей)
Дано: 100 млн DAU, пользователь открывает ленту 10 раз/сутки, публикует 2 поста/сутки, в среднем 300 подписчиков.
- Чтение:
100M × 10 / 86 400 ≈ 11.5k QPS avg, пик ×3 → ~35k QPS. - Запись постов:
100M × 2 / 86 400 ≈ 2.3k QPS. - Fan-out: каждый пост → 300 вставок в ленты подписчиков →
2.3k × 300 ≈ 700k вставок/св кэш лент. Вот здесь узкое место: не пост, а доставка. Отсюда выбор fan-out on write vs read и микс для селебрити (см. classic-designs.md §2).
2.4 Пример 3: bandwidth (видео-хостинг)
Дано: 10 тыс. загрузок/сутки × ~1 ГБ исходник; 100 тыс. просмотров/сутки, средний просмотр 5 мин при битрейте 3 Mbps ≈ 110 МиБ.
- Storage-рост:
10k × 1 ГБ = 10 ТБ/суткиисходников + транскоды ×3–5 версий → 30–50 ТБ/сутки. Через год — десятки ПБ: только объектное хранилище (S3-класс), никакой NAS. - Egress:
100k × 110 МиБ ≈ 10 ТБ/сутки→ средний поток10 ТБ / 86 400 с ≈ 120 МБ/с ≈ 1 Gbps, пик ×3–5 → 3–5 Gbps. Вывод: отдавать клиентам напрямую из кластера нельзя (дорого и медленно глобально) → CDN с offload 90 %+. - Транскодинг: 10k видео/сутки, минуты CPU на минуту видео → асинхронный пайплайн через очередь (обработка может отставать от загрузки на минуты — это приемлемо и проговаривается).
2.5 Гигиена оценок и пример Twitter (Alex Xu, гл. 2)
Правила из книги — как подавать прикидку на секции:
- Округлять до круглых чисел: не 11.64 МБ, а «примерно 10 МБ» — интервью про порядок, а не про точность.
- Записывать допущения (письменно/на доске): «предположим 100 млн DAU, 2 твита/день» — интервьюер сможет поправить, а не оспорить результат.
- Подписывать единицы: KB — килобайт, Kb — килобит (×8 разницы); латентность в мс, bandwidth в МБ/с.
- Пример книги (Twitter): 100M DAU × 2 твита ≈ 2300–3500 QPS запись; медиа ~30 ТБ/день; 5 лет ≈ 55 ПБ — порядок величин важнее цифр.
3. Классы хранилищ и критерии выбора
| Класс | Представители | Модель / движок | Сильные стороны | Слабые стороны | Когда выбирать |
|---|---|---|---|---|---|
| RDBMS | PostgreSQL, MySQL | B-tree, строгая схема, SQL/JOIN | ACID, транзакции, сложные запросы, зрелость, ограничения целостности | Вертикальный масштаб, шардирование вручную, дорогие high-write-нагрузки на большие объёмы | Деньги, заказы, связи сущностей; данные до единиц ТБ; консистентность важнее доступности |
| KV | Redis, DynamoDB, Cassandra | hash / LSM; O(1) по ключу | Гигантский RPS на ноду, горизонтальный масштаб, TTL | Нет JOIN и сложных запросов, ограниченная модель, у Redis — память | Сессии, счётчики, фичи-флаги, кэш, hot path по известному ключу |
| Document | MongoDB, Couchbase | JSON-документы | Гибкая схема, агрегаты «документ = объект домена», атомарность на документ | JOIN слабые, транзакции между документами — боль | Контент с вариативной структурой, каталоги, профили |
| Column / analytics | ClickHouse, HBase, Bigtable | columnar / LSM-семейство | Агрегации по миллиардам строк, сжатие, потоковая вставка | Нет точечных UPDATE, слабые транзакции | Логи, метрики, аналитика, отчёты, event store для чтения |
| Search | Elasticsearch, Solr, OpenSearch | инвертированный индекс | Полнотекстовый поиск, фасеты, морфология, fuzzy | Не источник правды (в конечном счёте eventual), дорогая запись | Поиск по тексту, автодополнение, логи-поиск |
| Time-series | Prometheus, InfluxDB, VictoriaMetrics | time-partitioned columnar | Даунсемплинг, retention, быстрые оконные агрегаты | Специализированная модель | Метрики, мониторинг, телеметрия |
| Graph | Neo4j | граф, index-free adjacency | Траверсы на глубину, связи N-го порядка | Редко нужно; операции на массовом графе дороги | Соцграф, рекомендации, fraud-цепочки |
| Object storage | S3, GCS, MinIO | blob по ключу | Почти бесконечный масштаб, дешевизна, 11 девяток durability | Высокая латентность, нет списков/запросов в реальном времени | Медиа, бэкапы, стейджинг для batch |
| Event log | Kafka | append-only partitioned log | Реплей, ретеншн, десятки МБ/с на партицию, порядок в партиции | Не queryable, порядок только в партиции | Интеграция сервисов, event sourcing, батчи-конвейеры |
Как отвечать на секции (по одному предложению на выбор): «Данные реляционные и за деньги → PostgreSQL; hot path по ключу с RPS, которые не тянет SQL → KV-зеркало/Redis; поиск → инвертированный индекс; аналитика → колоночная БД; медиа → S3 + CDN; событийная интеграция → Kafka. Источник правды один (RDBMS), остальные — производные проекции с известным лагом».
3.1 Движки хранения: LSM vs B-tree (DDIA 2-е изд., гл. 4)
Два семейства OLTP-движков — классический вопрос этапа 4 «а как внутри вашей БД»:
- LSM-tree (RocksDB, Cassandra, HBase, LevelDB): запись → memtable (отсортированная структура в памяти) → flush в SSTable (иммутабельные отсортированные файлы на диске, компрессия, sparse index); фоновая компактация сливает сегменты как mergesort; удаление — tombstone; Bloom filter отсекает чтение отсутствующих ключей; компактация size-tiered (сначала мелкие равного размера) vs leveled (уровни по размеру) — компромисс write/пространство.
- B-tree (PostgreSQL, MySQL, почти все RDBMS): страницы фиксированного размера, обновление на месте, глубина O(log n) — на практике 3–4 уровня (≈250 TB при branching factor ~500); page split при заполнении; надёжность через WAL (журнал до модификации страниц); copy-on-write варианты (LMDB) дают снапшоты.
- LSM vs B-tree: LSM — выше write throughput (только последовательные записи, ниже write amplification, лучше компрессия), плата — чтение старых ключей дороже (несколько SSTable), range слабее, компактация конкурирует за IO → латентность-спайки; B-tree — предсказуемое точечное чтение и range, плата — write amplification (WAL + запись страницы целиком). SSD: sequential > random даже на flash (erase block ~512 KiB).
4. Кэш
Стратегии: - Cache-aside (базовая): приложение читает кэш, при промахе — БД и запись в кэш; при записи — БД, кэш инвалидируется. Просто, консистентность через TTL. - Read-through / write-through: кэш-слой сам ходит в БД; запись идёт сквозь кэш. Строже, но дороже на запись. - Write-behind (write-back): запись в кэш, в БД — асинхронно батчами. Быстро, но риск потери при падении — проговаривать явно. - Refresh-ahead: предиктивное обновление горячего до истечения TTL (профилактика stampede).
Инвалидация: TTL (универсальная страховка), инвалидация по записи (delete, не update), версионированные ключи (key:v2), событийная инвалидация через шину (Kafka → удалить/прогреть). Классическая гонка «читатель успел положить старое после записи» → лечится коротким TTL; радикально — delayed double delete.
Cache stampede (thundering herd): истечение тысячи горячих ключей разом роняет БД. Защиты: (1) single-flight / distributed lock — один запрос пересчитывает, остальные ждут; (2) probabilistic early expiration (XFetch) — обновлять заранее с вероятностью, растущей от близости TTL; (3) разогрев и разнесённые TTL (jitter).
Прочее, что надо проговаривать: hit ratio цель 90 %+ для hot path; LRU как дефолт, LFU для неравномерных; hot key (селебрити) → локальный L1 + реплики ключа; метрики кэша обязательны (hit ratio, evictions, latency).
5. Репликация
- Leader–follower (базовая): запись на лидера, реплики тянут WAL/binlog. Sync — не теряем данные, платим латентностью; async — быстро, лаг и потери при failover; semi-sync — компромисс (ждём ACK одной реплики).
- Replication lag: read-your-writes ломается. Средства: читать свои записи с лидера (sticky), монотонное чтение с одной реплики, версионные токены (LSN), наблюдение за lag как SLO.
- Multi-leader: несколько пишущих узлов (мульти-ДЦ, оффлайн-клиенты). Плата — конфликты writes; решение: LWW (теряет данные), CRDT, ручное разрешение. На секции: «избегаю без необходимости».
- Leaderless (Dynamo-стиль): пишем в W реплик, читаем из R, при
W + R > Nчитаем свежее; hinted handoff, read repair, anti-entropy (Merkle-деревья). Tunable consistency. Членство/детект отказов — gossip-протокол (без центрального детектора = без SPOF); при недоступности «своих» узлов — sloppy quorum: пишем на ближайшие доступные с hint, отдаём владельцу позже (Alex Xu, гл. 6). - Failover: детект (heartbeat + кворум), выбор нового лидера, fencing старого (split brain = два лидера пишут — катастрофа), автоматический vs ручной (проговаривать: автоматика быстрее, но ложные failover дороже простоя).
- Что реплицируем (DDIA 2-е изд., гл. 6): statement-based (нестабильно: now()/rand()), WAL (привязан к версии движка), logical/row-based лог — переносимый компромисс, фундамент CDC; сессионные гарантии формулируются по позиции в логе (read-your-writes = «читай с реплики, дотянувшей позицию моей записи»; monotonic reads = приклеивание к реплике; consistent prefix reads = порядок причинных записей). Кворумы
W+R>Nдают свежесть, но не linearizability — см. §7.
6. Шардирование
Сначала — а надо ли? Лестница «до шардирования»: индексы → вертикаль (железо) → реплики на чтение → кэш → денормализация/проекции → и только потом шарды. Шардирование — последняя ступень, потому что оно ломает транзакции, JOIN и операции.
Стратегии: - Range: по диапазону ключа (даты, ID-отрезки). Плюс — range-запросы, минус — hot spot на «свежем» диапазоне. - Hash: равномерно, но нет range-запросов; перешардирование болезненное. - Consistent hashing: кольцо + виртуальные ноды (100–200 на ноду) → при добавлении/уходе узла переезжает ~1/N ключей, а не почти всё. Стандартный ответ на «как перекладывать шарды без даунтайма». - Directory: lookup-сервис хранит карту; гибко (неровные данные), но сама карта — точка отказа/кэширования.
Hot partition: селебрити/перегретый ключ перекашивает шард. Средства: salting (ключ + суффикс с последующей агрегацией), выделение горячего в отдельный шард/сервис, локальный кэш на ноде.
Шард-ключ — главное решение: выбирается по access pattern, менять после — переливка всех данных. Кросс-шардные транзакции и JOIN → избегать (денормализация, 2PC — осторожно, см. §7). Ребалансировка: удвоение числа шардов заранее, миграция в фоне с dual-read.
Поверх шардов (DDIA 2-е изд., гл. 7): - Вторичные индексы: local (каждый шард ищет сам → scatter-gather по всем шардам) vs global (сам распределён по ключу индекса — быстрее поиск, но отстаёт от записи и hot-spot-уязвим). - Сколько шардов: фиксированное число маленьких шардов заранее — миграции дешевле, но больше метаданных; динамическое расщепление — автоматика, но движущиеся границы. Не mod N (двигается почти всё). - Request routing: «где мои данные?» — слой маршрутизации + метаданные в координационном сервисе + кэш на клиенте; изменение членства — gossip/notifications. - Мультиарендность: tenant_id в ключе шарда; шумные соседи (noisy neighbors) изолируются выделенными шардами.
7. Консистентность и распределённые транзакции
- CAP: при сетевом разделении (P — не опция, оно случается) выбираем C или A. Формулировка для доски: «в одном ДЦ почти всегда C; между ДЦ — вынужденно AP с eventual».
- PACELC: даже без разделения (Else) платим Latency за Consistency или наоборот. Честнее CAP в обычной жизни: строгая консистентность = дополнительный round-trip.
- Модели: linearizability (выглядит как одна копия; дорого) → sequential → causal → eventual (дёшево, но аномалии: read-your-writes, monotonic reads нужно обеспечивать отдельно).
- Quorum:
W + R > Nгарантирует пересечение; настройка W=N/R=1 (строгая запись), W=1/R=N (строгое чтение), промежуточные — по чтению/записи. Конфликты параллельных версий отслеживаем векторными часами (счётчики по узлам в каждой записи): определяют причинность; параллельные ветки → отдаём клиенту обе версии, слияние вручную (Alex Xu, гл. 6, Dynamo). - 2PC (prepare/commit): строгая атомарность, но координатор — точка блокировки и отказа; на секции говорить: «в высоконагруженных системах избегаю, применяю саги».
- Saga: последовательность локальных транзакций + компенсирующие действия при откате (order → reserve → charge → ship; откат = cancel/refund). Оркестрация (координатор) vs хореография (события через шину).
- Transactional outbox: запись в БД и публикация события атомарно: событие пишется в outbox-таблицу в той же транзакции, отдельный воркер/CDC (Debezium) публикует в Kafka. Решает «БД записала, событие потерялось».
- Идемпотентность: точно-once между системами не существует — есть at-least-once + дедупликация (idempotency key, уникальные constraint, таблица обработанных).
Уровни изоляции и гонки (DDIA 2-е изд., гл. 8): read committed (нет dirty read/write: MVCC — читатели видят закоммиченные версии, row-lock на запись) → snapshot isolation (транзакция читает согласованный снапшот на старте) → serializable (2PL или SSI: MVCC + отслеживание опасных rw-антизависимостей → abort вместо блокировок). Гонки: lost update (read-modify-write; лечится SELECT FOR UPDATE / CAS / автоматическим детектом в MVCC), write skew (две транзакции читают пересечение, пишут разные строки — инвариант сломан; лечится serializable/constraint/материализацией конфликта), phantom (предикатные чтения → predicate locks).
Linearizability vs serializability (DDIA 2-е изд., гл. 10, вопрос-ловушка): linearizability — гарантия свежести одной операции («после завершения записи все читают новое», система выглядит как одна копия); serializability — гарантия изоляции транзакций (порядок любой, если эквивалентен последовательному). Вместе = strict serializability (Spanner, FoundationDB). Нужна для: lock/leader election, uniqueness-ограничений, cross-channel timing. Дают: single-leader (пока лидер настоящий) и консенсус; кворумы W+R>N НЕ дают (гонки concurrent read repair; LWW по wall-clock — тем более теряет данные).
Часы и порядок (DDIA 2-е изд., гл. 9–10): time-of-day (NTP, прыжки, drift до 200 ppm) против monotonic (только интервалы). Lamport clock (counter+nodeID) и hybrid logical clock (HLC) дают total order, согласованный с причинностью — но не linearizability; параллельность детектируют только vector clocks (дороже по размеру). ID: автоинкремент = linearizable fetch-and-add; Snowflake/UUIDv4/ULID теряют порядок.
Консенсус (DDIA 2-е изд., гл. 10): эквивалентные формулировки — single-value consensus, linearizable CAS, shared log (total order broadcast), atomic commit, fetch-and-add; свойства agreement/integrity/validity (safety — держится всегда) + termination (liveness — требует большинства живых). Механика: epoch/term, уникальный лидер эпохи, два голосования (выборы + коммит) с пересекающимися кворумами. Практика — координационные сервисы (ZooKeeper/etcd/Consul): locks/leases + fencing tokens (zxid/cversion в ZooKeeper, revision в etcd, epoch в Kafka; term/ballot в Raft/Paxos) + failure detection (сессии, ephemeral nodes) + change notifications; service discovery — кэшировать (observers).
Распределённые транзакции на практике (DDIA 2-е изд., гл. 8): 2PC/XA — in-doubt транзакции держат локи при падении координатора, «heuristic decisions» ломают атомарность; NewSQL (CockroachDB, Spanner, TiDB, FoundationDB, транзакции Kafka) — реплицированный координатор на консенсусе, без XA-болей. Exactly-once без распределённых транзакций: таблица обработанных message-ID в локальной транзакции = идемпотентный консьюмер (так делает Kafka Streams).
8. Очереди и потоковая обработка
Зачем: развязка сервисов, буферизация пиков (load leveling), ретраи, broadcast, порядок и реплей. Плата: лаг, дубли, сложность отладки.
Kafka — словарь: topic → партиции (порядок и параллелизм внутри партиции; ключ маршрутизирует), consumer group (каждая партиция — одному консьюмеру группы), offsets (позиция, коммитится; реплей с любого offset), retention по времени/размеру (лог можно перечитать), ISR для надёжности, acks=all для данных, которые нельзя терять.
Delivery semantics: - At-most-once — может потерять, не дублирует (fire-and-forget). - At-least-once — дефолт надёжных систем; дубли неизбежны → потребитель обязан быть идемпотентным. - Effectively-once — at-least-once + дедуп (Kafka transactions / idempotent producer / ключи дедупа на стороне потребителя).
Паттерны: DLQ для ядовитых сообщений, backpressure (не тащим быстрее, чем можем обработать), competing consumers для масштаба, приоритетные очереди (отдельные топики), dead man's switch на затишье.
Группы потребителей (DDIA 2-е изд., гл. 12): одна consumer group — load balancing (партиция — одному консьюмеру группы), разные группы — fan-out (каждая получает всё); acknowledgments + redelivery. Обычные брокеры (AMQP/RabbitMQ) — delete-after-delivery; log-based (Kafka) — append-only партиции, consumer offsets, retention и реплей.
CDC и компоновка (DDIA 2-е изд., гл. 12): CDC — репликационный лог БД → стрим (Debezium/Kafka Connect): БД не знает об этом, исторические данные — через initial snapshot + offset; log compaction — по ключу хранится только последнее значение (навсегда), а не окно по времени. CDC (факты изменений) ≠ event sourcing (намерения домена). Окна: tumbling/sliding/session; event time vs processing time (часы клиентов плывут — watermarks для закрытия окна).
9. Отказоустойчивость
Изоляция и деградация:
- Timeout на каждый внешний вызов — без него один зависший dependency съедает потоки.
- Retries: экспоненциальный backoff + jitter; только идемпотентные операции; ограничение числа попыток.
- Circuit breaker: closed → (ошибки > порога) → open (фейлим сразу, дёшево) → half-open (пробный запрос). Защищает от каскадного падения и даёт зависимости время восстановиться.
- Bulkhead: отдельные пулы соединений/потоков на dependency; падение одного не топит остальные.
- Rate limiting: token bucket / leaky bucket / sliding window; на клиенте (борьба с абузой) и на сервере (self-protection); 429 + Retry-After; в распределёнке — Redis + Lua или лимитер на шлюзе.
- Load shedding: при перегрузке отказываем «дешёвым» запросам, спасаем критичные; graceful degradation — отдаём кэш/неполные данные вместо ошибки.
Резервирование: N+1 на каждом ярусе; active–active (мульти-ДЦ, дороже, выше утилизация) vs active–passive (проще, тёплый простой). Health checks (liveness/readiness), автоматический failover с кворумом.
Арифметика надёжности: доступность цепочки = произведение; параллель = 1 − ∏(1−ai). «Три девятки» = 8.7 ч/год — уже требует резервирования всего пути.
Слабые места распределённой среды (DDIA 2-е изд., гл. 9): - Partial failure — норма: «работает или нет» больше нет; сеть асинхронна — потерянный запрос, очередь, упавшая нода, GC-пауза, потерянный ответ не отличить; таймаут — догадка; «нет ответа» ≠ «не выполнилось» → ретраи только для идемпотентного. - Часы: time-of-day (NTP: прыжки, drift) для wall-clock опасен (LWW теряет данные), интервалы — только monotonic; между машинами время несравнимо. - Process pauses / зомби-лидер: GC, VM suspend, swap — нода «засыпает» на секунды, не замечая истёкшего lease; защита — fencing token на каждом grant, хранилище отвергает старые (см. §7). - Кворум объявляет мёртвым — нода обязана подчиниться: узел знает только полученные сообщения; majority-кворум — единственный с гарантированным пересечением. - System models: реалистичная — partially synchronous + crash-recovery; safety (не нарушается никогда) vs liveness («eventually», при живом большинстве); Byzantine (враньё узлов) — вне охвата датацентров, от слабого вранья — checksums/валидация входа; gray failure (limping node) — хуже чистого отказа.
10. Эксплуатация (говорим на секции всегда)
- Golden signals (Google SRE): latency (отдельно ошибки и успехи!), traffic, errors, saturation. Метрики каждого яруса: QPS, p50/p95/p99, error rate, очередь/лаг, утилизация (CPU, память, соединения).
- SLI/SLO/SLA + error budget: SLO 99.9 % даёт бюджет 43 мин/мес; бюджет кончился — фризим фичи, чиним надёжность. На секции это маркер production-зрелости.
- Релизы: rolling, canary (1 % → 10 % → 50 % → 100 % с авто-откатом по метрикам), blue-green (мгновенный откат переключением), feature flags (расходим деплой и релиз фичи).
- Миграции без даунтайма — expand/contract: 1) расширяем схему (новая колонка/таблица, nullable, backfill в фоне), 2) двойная запись/чтение-сравнение, 3) переключаем чтение, 4) контракт: убираем старое. Каждый шаг — рабочий релиз. Antipattern: большие миграции ALTER на живых больших таблицах и dual writes без сверки.
- Наблюдаемость: metrics (Prometheus) + logs (структурированные) + traces (OpenTelemetry, сквозной trace id). Алерты на симптомы (SLO burn), а не на причины.
- Ёмкость: план на пики (реклама, праздники), headroom ≥ 2×, регулярный load-тест.
- Хвостовая латентность и metastable failure (DDIA 2-е изд., гл. 2): считать p50/p95/p99, среднее врёт; tail amplification — один медленный вызов в fan-out-цепочке тянется в общую p99 (N бэкендов → почти каждая страница ловит хвост). Metastable failure: перегруз → таймауты → retry storm → система «застревает» в перегрузе даже после спада нагрузки; лечится exponential backoff + jitter, circuit breaker, load shedding, backpressure. Словарь: response time ≠ service time ≠ latency (очередь — главный источник задержки).
11. Мини-шпаргалка «что назвать на секции»
| Тема | Обязательная лексика |
|---|---|
| Оценка | DAU → QPS avg/peak, storage с retention, bandwidth, 80/20 для кэша |
| Хранилище | источник правды RDBMS, проекции под access pattern, критерии выбора класса |
| Масштаб | кэш → реплики → шардирование; consistent hashing, virtual nodes, hot partition |
| Консистентность | CAP/PACELC, quorum, лаг репликации, saga/outbox вместо 2PC, идемпотентность |
| Очереди | Kafka, партиции, at-least-once + дедуп, DLQ, load leveling |
| Отказы | timeout/backoff/jitter, circuit breaker, bulkhead, rate limit, graceful degradation |
| Эксплуатация | golden signals, SLO/error budget, canary, expand-contract миграции |
12. Карта DDIA (Клеппман, «Высоконагруженные приложения»)
⚠️ Карта ниже — по 1-му изданию (= русский перевод). Вышло 2-е издание (Kleppmann & Riccomini, 2025, 673 стр.): гл. 1 переписана, гл. 2 новая (НФТ + кейс лент), старые гл. 5–9 → 6–10, + логические часы и ID-генераторы, + durable execution/workflow engines в гл. 5. Соответствие глав и приоритеты 2-го изд. (6–10 ядро, 1–5 вторично, 11–13 опционально, 14 — этика) — materials/ddia-map.md §0; полный текст 2-го издания с выжимками — materials/ddia-2ed/ch-*.md (TASK-45.39).
Приоритеты: ЯДРО — читать обязательно, именно отсюда вопросы секции; вторично — к интервью после ядра; опционально — после секций / для общего развития.
Часть I. Основы данных (главы 1–4)
| Глава | Тема | Приоритет | Что брать на секцию |
|---|---|---|---|
| 1 | Надёжность, масштабируемость, поддерживаемость | ЯДРО (быстро) | Словарь: нагрузка → латентность p99 → эластичность; «сначала описать нагрузку, потом решать» |
| 2 | Модели данных и языки запросов | Вторично | Реляционная vs документная: локальность данных vs связи; когда NoSQL оправдан |
| 3 | Хранение и извлечение | ЯДРО | LSM vs B-tree — любимый вопрос: LSM — быстрый write, компактация, read amplification; B-tree — быстрый read, предсказуемость; плюс хеш-индексы, SSTable |
| 4 | Кодирование и эволюция | Вторично | Обратно-совместимые схемы (protobuf/Avro), зачем schema registry; старые и новые читатели |
Часть II. Распределённые данные (главы 5–9) — сердце книги и секции
| Глава | Тема | Приоритет | Что брать на секцию |
|---|---|---|---|
| 5 | Репликация | ЯДРО | Sync/async, лаг, read-your-writes, failover, split brain, multi-leader конфликты |
| 6 | Партиционирование | ЯДРО | Range vs hash, hot skew/celebrity, ребалансировка, запросы по нескольким шардам |
| 7 | Транзакции | ЯДРО | Уровни изоляции, race conditions (dirty/phantom/lost update), serializable snapshot isolation |
| 8 | Проблемы распределённых систем | ЯДРО | Partial failure, неопределённость ответа (timeout — «не знаю»), часы и порядок событий, GC-паузы как «зомби»-процессы |
| 9 | Консистентность и консенсус | ЯДРО (самая плотная) | Linearizability, CAP/PACELC, кворумы, fencing-токены, RAFT/Paxos на уровне идей, зачем ZooKeeper/etcd |
Часть III. Производные данные (главы 10–12)
| Глава | Тема | Приоритет | Что брать на секцию |
|---|---|---|---|
| 10 | Пакетная обработка | Опционально | MapReduce-идея, partition-parallel batch, когда batch вместо stream |
| 11 | Потоковая обработка | Вторично | Delivery semantics, exactly-once иллюзия, окна, переработка (replay) — прямо ложится на вопросы про Kafka |
| 12 | Будущее | Опционально | Общая картина: deriving state from event log |
Порядок чтения к слотам (18.09 / 21.09 / 22.09)
- До слота 18.09: гл. 1, 3, 5, 6 (+ детальный конспект URL shortener из статьи Яндекса). Это скелет: числа, хранение, репликация, партиции.
- Между 18.09 и 21.09: гл. 7, 8, 9 — транзакции, отказы, консистентность/консенсус. Самое плотное ядро.
- Перед 22.09: гл. 11 + повтор конспектов по ч. II; гл. 2, 4 — по остатку времени.
- Гл. 10 и 12 — после секций, для собеседований уровнем выше.
- После каждой главы — 5-минутный пересказ схемы вслух у доски (протокол тренировки — methodology.md).
Детальная проработка карты чтения и привязка к слотам — materials/ddia-map.md (TASK-45.10).
13. Инфографика System Design Blueprint (learn-system-design) — карта и дополнения
Источник: system-design-guide.jpeg из подборки learn-system-design («System Design Blueprint: The Ultimate Guide», TASK-45.12): весь путь запроса на одном листе — DNS → балансировщик → API-шлюз → бэкенды → кэш/очереди → БД → хранение медиа, плюс сквозные темы. Большая часть уже покрыта §3–§11; ниже — карта «блок → где в KB» и мини-блоки, которых не хватало. Полная послойная расшифровка — ✅ TASK-45.24 (materials/lsd-ultimate-guide-image.md), индекс всей подборки — materials/learn-system-design-index.md.
| Блок инфографики | Что на листе | Где в KB |
|---|---|---|
| DNS | resolver → root → TLD → authoritative, GeoDNS, кэш/TTL | §13.1 (новое) |
| API-шлюз | валидация, auth, rate limit, TLS, idempotency key, логи | §9 + §13.7 |
| Load Balancing | алгоритмы + метрики выбора ноды | §13.2 (новое) |
| Real-time транспорт | WebSocket/SSE/polling/webhook/WebRTC/RTMP | §13.3 (новое) |
| Бэкенды | fan-out, конкурентность, распределённые локи, генерация ID | §13.4–13.5 (новое), §7 (идемпотентность) |
| Cache | стратегии записи, eviction, инвалидация | §4 (уже есть) |
| Database | классы хранилищ, шардирование, кворумы, Merkle | §3, §5–§7 + §13.6 (гео) |
| Upload медиа | чанки, signed URL, metadata-таблица, транскодинг | classic-designs §4 |
| Очереди/метрики | лаг, in-transit, golden signals | §8, §10 |
| Платежи | charge-сервис, внешний banking, идемпотентность | §13.7 (новое), §7 |
| Security | OAuth/RBAC, шифрование, audit trail | §13.7 (новое) |
Послойная расшифровка листа и маппинг «блок → где в KB» — materials/lsd-ultimate-guide-image.md (TASK-45.24); ниже §13.1–13.7 — мини-блоки с формулировками, §13.8 — дополнения по итогам полной расшифровки.
13.1 DNS — одной фразой на секции
Цепочка: клиент → рекурсивный resolver (ISP) → root NS → TLD NS (.com) → authoritative NS → IP; каждый уровень кэшируется с TTL. GeoDNS отдаёт IP ближайшего региона — с этого начинается «мульти-ДЦ». Формулировка: «клиент резолвит домен, GeoDNS ведёт в ближайший регион, дальше весь трафик — в LB». Не углубляться.
13.2 Алгоритмы балансировщика
Round Robin (stateless-дефолт) • Weighted RR (ноды разной мощности) • Least Connections (долгие соединения: websocket/streaming) • Hash/IP-sticky (сессии, кэш-локальность; вместе с consistent hashing — ответ про масштабирование пула LB) • Random (говорим, что не выбираем). Обязательная фраза: «перед LB — health checks, нездоровую ноду выбрасываем из ротации».
13.3 Real-time транспорт — выбор по направленности и совместимости
| Механизм | Направление | Когда выбирать |
|---|---|---|
| WebSocket | дуплекс | мессенджер, коллаб-редактор, live-обновления (см. classic-designs §3); LB — least connections/sticky, ping/pong keepalive |
| SSE | сервер → клиент | нотификации, лента: проще WS, поверх HTTP, авто-reconnect |
| Long polling | сервер → клиент | старые клиенты/прокси, где WS не проходит |
| Short polling | клиент опрашивает | простые статусы; называем цену: холостые запросы |
| Webhook | сервер → сервер | push событий наружу (интеграции) |
| WebRTC / RTMP | P2P медиа / ingest | звонки; приём видеопотока → дальше HLS/DASH + CDN |
13.4 Распределённая генерация ID (URL shortener, лента, заказы)
- UUID v4: без координации, но 128 бит и нет порядка → плохие индексы и шардирование по времени.
- Auto-increment × N нод (чёт/нечет или шаг N): просто, но плохо масштабируется и предсказуемо.
- Snowflake (64 бита: 41 время + 10 нод + 12 секвенция): хронология «бесплатно», дружелюбно индексам и шардированию; семейство — Baidu UID, Sonyflake. Дефолтный ответ для ID сущностей в масштабе.
- Централизованный генератор (ticket service): просто, но точка отказа; лечится кэшированием диапазонов.
13.5 Распределённые локи и координация
Redis (Redlock) — быстро, компромисс по надёжности; ZooKeeper/etcd/Chubby — кворумные, надёжнее и дороже. Применение: leader election, single-flight пересчёт кэша (stampede, §4), дедуп критичных операций. Оптимистичная блокировка (версия/CAS) — дефолт; пессимистичная — короткие критические секции. При локах проговаривать fencing token и «лок ≠ транзакция» (§5, §7).
13.6 Гео-шардирование и пространственные данные
Гео-шарды (по регионам): локальность данных, latency, GDPR-границы; цена — кросс-региональная консистентность (§7). Запросы «ближайшие N объектов» — geohash/QuadTree + R-деревья; на задачах Uber/карт-класса это ключевой блок выбора БД.
13.7 Платежи и security — сквозные темы секции
Платежи: charge-сервис с idempotency key (повтор запроса ≠ двойное списание), статус-машина платежа, внешний banking-провайдер = медленная зависимость → таймаут/ретрай/очередь + сверка (reconciliation). Ошибки домена (карта просрочена, недостаточно средств, провайдер недоступен) — обрабатываемые ветки, не 500.
Security-чеклист (назвать всегда): OAuth 2.0/JWT, RBAC, TLS in-transit + шифрование at-rest, audit trail, input validation, signed URLs на приватные объекты (медиа), rate limiting (§9).
13.8 Дополнения по полной расшифровке листа (TASK-45.24)
Мини-факты, которых не было в §1–13.7; формулировки — как на листе, добавлена расшифровка «зачем»:
- API-шлюз, ответная сторона (просим не забыть): gzip/deflate, Request ID (трассировка), pagination, expiry-заголовки (кэш-контроль), mime, cookie, коды/тексты ошибок. Запросная сторона: валидация, auth (OAuth 2.0), rate limit, whitelist/blacklist, flow control, TLS termination, дедуп по idempotency key, metering/диспетчеризация.
- CDN — push hot / pull rare / hybrid: горячее проталкиваем на край заранее, редкое тянем по промаху, обычно гибрид; метрики края — cache miss outs, active/total resources.
- Генерация ID — offline generations: генератор выдаёт нодам диапазоны заранее — сервис не стоит на критическом пути записи (дополняет snowflake, §13.4).
- Конкурентность — serially batch: между «строго последовательно» и пессимистичными локами есть промежуточная ступень — последовательные батчи (дополняет §13.5).
- Upload медиа — metadata-таблица чанков:
key | checksum | timestampв in-memory key storage, целостность чанка проверяем по checksum при каждом чтении, таблицу синхронизируем централизованно; событие «новый чанк» фан-аутится в MQ → воркеры (транскодинг: compute time, failed count, encoded/compression ratio, storage consumed). - Рекомендации — фильтры: content-based (по признакам контента) и collaborative (по поведению похожих пользователей) — назвать обе, если в системе есть лента/каталог.
- Метки наблюдаемости листа развешаны по компонентам (шлюз: 4XX/5XX/2XX, response time; очередь: count, consumption rate, in-transit waiting-for-ack, queue limit; БД: query time, throughput, active connections) — так и подавать на этапе 6: метрики привязаны к узлу, а не списком в конце.
14. Строительные блоки из Alex Xu Vol. 1 (TASK-45.38)
Источник: «System Design. Подготовка к сложному интервью» (рус. Vol. 1), полный текст глав — materials/alex-xu-vol1/ch-*.md, карта переноса — materials/alex-xu-vol1/_map.md. Здесь — паттерны, которых не было в §1–13: алгоритмы rate limiting (гл. 4), краулер (гл. 9), уведомления (гл. 10), автозаполнение (гл. 13), блочное хранилище (гл. 15). Snowflake — §13.4; транспорт (polling/WS) — §13.3; consistent hashing — §6; Dynamo-механики — §5/§7.
14.1 Алгоритмы rate limiting (гл. 4)
| Алгоритм | Память | Плюсы | Минусы |
|---|---|---|---|
| Token bucket | O(размер корзины) | допускает burst, гибкая настройка скорости | два параметра |
| Leaking bucket | O(размер очереди) | ровный выходной поток | burst режется; два параметра |
| Fixed window counter | O(счетчиков) | просто | burst ×2 на границе окон |
| Sliding window log | O(запросов) | точно | дорого по памяти |
| Sliding window counter | O(счетчиков) | компромисс (гибрид двух) | оценка, не точный лимит |
Распределённый лимитер: Redis + Lua (атомарный check-and-set, иначе race между воркерами); multi-DC → лимитер на edge (GeoDNS → ближайший узел), консистентность между узлами — eventual, учесть в бенчмарках. Эксплуатация: заголовки X-RateLimit-*, код 429, мониторинг доли заблокированных (высокая = абьюз или неверный лимит). Клиентские лимитеры (в приложении) — для экономии вызовов, серверные — источник правды.
14.2 Поисковый краулер (гл. 9)
Характеристики: масштабируемость, устойчивость, вежливость (не DDoS чужие серверы), расширяемость (плагины). Компоненты: seed URL → frontier (очередь на загрузку) → загрузчик HTML (+DNS-кэш — узкое место, 10–200 мс) → дедуп контента по хешам (29 % страниц — дубликаты; фильтр Блума для «видели URL?») → извлекатель ссылок → фильтр URL → хранилище URL.
Frontier — сердце: лицевые очереди (приоритет: PageRank, популярность, частота обновления) + тыльные очереди (вежливость: домен → таблица связывания → своя FIFO → выделенный рабочий поток с задержкой). BFS «в лоб» бьёт по одному домену и не учитывает ценность страниц. Ещё: robots.txt (кэшировать, уважать Disallow), гео-распределение, timeout на медленные серверы, состояние в хранилище (рестарт после сбоя), спайдертрапы (лимит длины URL, чёрные списки), server-side рендеринг JS-страниц.
14.3 Система уведомлений (гл. 10)
Каналы: APNs (iOS) / FCM (Android) / Twilio-Nexmo (SMS) / SendGrid-Mailchimp (email) — провайдеры сторонние, расширяемость обязательна (FCM недоступен в Китае → JPush). Паттерн: сервисы → серверы уведомлений (API, валидация, шаблоны) → очередь на каждый канал (отказ одного провайдера не роняет остальные) → воркеры → провайдеры. Надёжность: уведомление не теряется — журнал уведомлений в БД + retry из очереди; доставок может быть больше одной (at-least-once) → дедуп по ID события; rate limiting на получателя (иначе отписки); мониторинг длины очередей (растёт → добавляем воркеров); аналитика (открытия/клики/отписки), настройки opt-in. Это же — типовой ответ «как связать сервис с внешним миром».
14.4 Автозаполнение поиска / typeahead (гл. 13)
Требования: <100 мс, топ-5 по частоте, совпадение с начала строки. Прикидка: 10M DAU × 10 запросов × 20 символов ≈ 24k QPS (пик 48k) — запрос на каждый введённый символ. Ядро — trie (префиксное дерево) с частотами; наивный алгоритм O(p) + O(c) + O(c log c). Две оптимизации до O(1): (1) ограничить максимальную длину префикса; (2) топ-k популярных запросов прямо в каждом узле — память платим, латентность забираем. Данные строятся offline: логи → агрегаторы (частоты за период; для Google хватает недели, для Twitter — реальное время) → воркеры пересобирают trie → БД (документная/снимок или KV «префикс → список») → кэш trie в памяти → API. Шардирование — по диапазонам префиксов. Вариант вопроса «top-k самых частых запросов» — это он.
14.5 Блочное хранилище и синхронизация файлов (гл. 15, Google Drive/Dropbox)
Файл → блоки (~4 МБ) → сжатие по типу → шифрование → S3; метаданные (блоки + хеши, версии) — в реляционной БД (ACID): нужна строгая согласованность между кэшем и БД, инвалидация кэша при записи. Экономия трафика: дельта-синхронизация (передаём только изменённые блоки), дедупликация (одинаковый хеш = один блок), лимит версий, холодное хранилище (Glacier) для неактивного. Конфликты одновременного редактирования: побеждает первая обработанная версия, второму клиенту — обе версии на слияние/выбор. Уведомления об изменениях — long polling (одностороннее, редкие события — WebSocket избыточен); оффлайн-клиент — очередь автономной архивации. Таблицы: user, device (push_id), namespace, file, file_version (immutable), block.
15. Кодирование, эволюция схем и durable execution (DDIA 2-е изд., гл. 5)
Мини-блок под вопросы «как менять формат данных без даунтайма» и «какие alternatives сагам есть":
- Совместимость: backward (новый код читает старые данные) и forward (старый код — новые): обязательны при поэтапных релизах; потоки данных — через БД («сообщение будущему себе»), через сервисы (REST/RPC), через сообщения (брокер).
- Форматы: JSON/CSV — читаемые, объёмные, двусмысленность чисел; Protobuf/Avro — компактные, эволюция через схему (protobuf — теги полей, новые поля с новыми номерами; Avro — writer/reader schema, идеален для CDC), проверка совместимости до деплоя (schema registry).
- RPC не может спрятать сеть: частичные отказы, таймауты, семантика ретраев — те же проблемы, что у распределённых систем (§9).
- Durable execution / workflow engines (Temporal, Restate) — новое во 2-м изд.: оркестратор персистит состояние workflow в журнал, задачи идемпотентны и ретраятся движком; практическая альтернатива сагам и распределённым транзакциям для долгих бизнес-процессов (заказы, платежи, онбординг). На секции: «сага — дефолт; для долгих многошаговых процессов смотрю в сторону workflow-движков с durable execution».
Связанные документы
../interview-materials.md— общая карта материалов по вакансииmaterials/— конспекты источников (статья Яндекса, System Design Primer, habr 516604, видео Gabbard, DDIA) +learn-system-design-index.md(индекс подборки, TASK-45.12) +lsd-ultimate-guide-image.md(расшифровка инфографики, TASK-45.24) +alex-xu-vol1/(книга Алекса Сюя, полный текст глав + выжимки + карта переноса_map.md, TASK-45.38) +ddia-2ed/(DDIA 2-е издание, полный текст глав + выжимки + карта переноса_map.md, TASK-45.39)methodology.md— фреймворк ответа, тайминг, план тренировки (TASK-45.2)classic-designs.md— эталонные разборы сервисов (TASK-45.3)../algo-exam/complexity-cheat-sheet.md— методичка по алгоритмам (этап 1, закрыт)