---
title: Конспект материала 27 — system-design-resources (InterviewReady)
source: https://github.com/InterviewReady/system-design-resources
author: InterviewReady (interviewready.io) — курируемая подборка «лучших ресурсов по System Design»: 183 ссылки в ~38 разделах, 72 уникальных домена
конспект: подготовлено 2026-09-18, TASK-45.31; README прочитан целиком, все ссылки классифицированы по уникальности; топ-5 отобраны и прочитаны полностью — The Log (Kreps), Transactional Outbox (microservices.io), Uber CacheFront (via web.archive), LSM-tree (O'Neil, PDF), GSLB Page of Shame + Shopify DNS (via web.archive для Shopify)
статус: P3-источник «после секций», но топ-5 — не кейсы компонентов (их закрыл материал 26), а **следующий слой вглубь**: внутренности подсистем (хранилища, лог/потоки, атомарность публикации, кэш внутри движка БД) и глобальный слой отказоустойчивости (DNS/GSLB). Это ответы на уточняющие вопросы интервьюера «а как это устроено внутри». Учебников и шпаргалок в репо нет — это галерея внутренностей реальных систем
---

# Материал 27: system-design-resources (InterviewReady) — индекс и топ-5

Подборка устроена иначе, чем learn-system-design (стратегия и шпаргалки) и awesome-scalability (кейсы компаний по проблемам): это **коллекция «внутренностей»**: инженерные посты конкретных компаний (Netflix, Facebook/Meta, Uber, LinkedIn, Pinterest, Shopify) + академические первоисточники в полном тексте (BigTable, Dynamo, MapReduce, Gorilla, LSM-tree, Sagas, TCP congestion, Jeff Dean). Много элементов, которых нет ни в одной из уже разобранных подборок: DB-as-queue antipattern (4 ссылки), CDC-фреймворки, SPOF/DNS GSLB, authorization, collab-редактирование (Operational Transform), chess engine design. Слабости: нет обучения «с нуля», часть ссылок ведёт на платный курс interviewready.io, одна ссылка битая (критичный момент — опечатка `jenpsen.io` вместо `jepsen.io` в разделе Testing Distributed Systems), несколько статей 2004–2014 годов (ценность историческая, но механика не менялась).

## 1. Как устроен источник

| Кластер разделов | Что внутри | Доля (~) | Ценность для нас |
|---|---|---|---|
| **Хранилища и индексы** | NoSQL internals (Cassandra, BigTable, Dynamo), NoSQL algorithms (LSM-tree, SSTable/compaction, HyperLogLog, индексы), Time Series DBs (Pinterest Goku, Uber AresDB, **Facebook Gorilla**), replication (MySQL, **DBLog CDC**, **The Log**, LedgerStore) | ~25 ссылок | **Ядро** — внутренности слоя данных (KB §5–§6, §8) |
| **Интеграция и потоки данных** | Intra-service messaging, Message Queue Antipattern (DB-as-queue ×4), Event Driven Architectures (Fowler, martinfowler), Batch (MapReduce), Real-time stream (Brooklin, Keystone, ksqldb), Distributed Transactions (SAGA, Transactional outbox) | ~35 ссылок | **Ядро** — атомарность и потоки (KB §7–§8) |
| **Отказоустойчивость и сеть** | Single Point of Failure (DNS SPOF, GSLB, active-active Netflix, sharding), Load Balancing (consistent hashing, sticky, subsetting), Network Protocols (QUIC, TCP, WebRTC, HTTP HOL), Rate limiting, Testing distributed systems | ~30 ссылок | **Ядро** — вторая половина брифа (KB §3, §9, §11) |
| **Кэш и производительность** | Caching (Guava, Caffeine, modern cache, MS guide, **Uber 40M RPS CacheFront**), Capacity estimation (Jeff Dean, AWS BOE), In-memory DB / Redis | ~15 ссылок | Кэш-слой (KB §4); часть закрыта 45.30 |
| **Практический дизайн систем** | Messenger NYE, YouTube architecture, Distributed Design Patterns (horicky), monolith→microservices, Zerodha | ~20 ссылок | Эшелон 2 — референсы «ответ целиком» |
| **Прикладные домены** | Video processing (transcoding, shot-based), Google Docs / OT, Subscription management, Chess engine, API design, Authorization | ~25 ссылок | Вне брифа (но OT и video — классические вопросы) |
| **Инфраструктура** | Cluster/workflow mgmt (Twine, Autopilot, Conductor, Luigi), containers (Twine, Cloudflare), service mesh, distributed consensus (Paxos, Raft), distributed logging/tracing, alerts/anomaly detection | ~30 ссылок | Эшелон 2 — эксплуатация (KB §10) |
| Остальное | System Design Resources (DDIA, whtpapers), SD online judge | ~5 ссылок | Навигация (платное) |

## 2. Критерии отбора топ-5

1. Прямая релевантность брифу: крупноблочная схема Instagram/Twitter + отказоустойчивость. Материал 26 закрыл **компоненты** (ID, соцграф, кэш лент, деградация-механизмы) — здесь берём **следующий слой вглубь**: механика хранилищ, потоков и глобальной деградации, которой отвечают на «а как это устроено внутри».
2. Не дублировать уже покрытое: кэш-кейсы есть (FB/Memcached 45.16, Twitter/Redis 45.30), поэтому из кэша берём **Uber CacheFront** (интегрированный кэш внутри движка БД — другой класс решения); теория потоков есть в учебниках — берём **первоисточник The Log**; консистентность (KB §7) закрыта учебниками — берём **Transactional Outbox** (атомарность «запись + событие», нужна в fan-out схеме).
3. Доступность и полнота: все топ-5 прочитаны целиком (Uber и Shopify — через web.archive, обе версии совпадают с оригиналами); избегаем member-only статей (Airbnb — только тизер, честно вынесен во второй эшелон).
4. Ощутимая ценность «одной фразы на секции»: каждый топ-материал даёт маркер-цитату, которой нет в наших учебниках.

## 3. Топ-5

| # | Материал | Кто / год | Слой системы | Бриф / KB |
|---|---|---|---|---|
| 1 | [The Log: What every software engineer should know about real-time data's unifying abstraction](https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying) | Jay Kreps (LinkedIn/Confluent), 2013 | потоки и репликация: лог как объединяющая абстракция | бриф 07 / KB §5, §8 |
| 2 | [Transactional Outbox (microservices.io)](https://microservices.io/patterns/data/transactional-outbox.html) (+ companion: [SAGAS (Cornell PDF)](https://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf)) | Chris Richardson / Garcia-Molina & Salem | атомарность «запись в БД + публикация события» | бриф 07, 09 / KB §7, §8 |
| 3 | [How Uber Serves Over 40 Million Reads Per Second Using an Integrated Cache](https://www.uber.com/en-IN/blog/how-uber-serves-over-40-million-reads-per-second-using-an-integrated-cache) | Uber, 2022 | кэш-слой внутри движка БД: cache-aside + CDC-инвалидация | бриф 06 / KB §4, §9 |
| 4 | [The Log-Structured Merge-Tree (LSM-tree)](https://www.cs.umb.edu/~poneil/lsmtree.pdf) (+ [SSTable & compaction strategies (Scylla wiki)](https://github.com/scylladb/scylla/wiki/SSTable-compaction-and-compaction-strategies)) | O'Neil, Cheng, Gawlick, O'Neil — Acta Informatica 1996 | внутренности write-оптимизированных хранилищ (Cassandra/Dynamo/RocksDB) | бриф 04–05 / KB §5, §6 |
| 5 | [Why DNS-based GSLB Doesn't Work](http://www.tenereillo.com/GSLBPageOfShame.htm) (+ [Shopify: Intro to DNS Traffic Management](https://shopify.engineering/introduction-dns-traffic-management)) | Tenereillo 2004 / Shopify 2023 | глобальный слой отказоустойчивости: DNS, TTL, мульти-region | бриф 08 / KB §3, §9 |

### 3.1 The Log — Jay Kreps (2013) — лог как объединяющая абстракция

**Выжимка.** Самая известная статья про потоковые системы: **лог = append-only, тотально упорядоченная последовательность записей**, где позиция записи — «время» без физических часов. Из неё вырастает **State Machine Replication Principle**: «если два одинаковых детерминированных процесса стартуют в одном состоянии и получают одинаковые входы в одинаковом порядке, они произведут одинаковый выход» — вся репликация сводится к доставке одного лога. **Двойственность таблиц и логов**: таблица = проекция лога («балансы» из «кредитов/дебетов»); из лога можно пересобрать не только текущее состояние, но и все производные таблицы/индексы; наоборот, из таблицы вытаскивается changelog — ровно то, что нужно для CDC. Практические следствия: **лог как отдельный сервис** решает data integration (все данные организации — в центральный лог, каждый подписчик читает в своём темпе, добавление подписчика не меняет продюсера); лог — это **буфер**, который отвязывает продюсера от консьюмера (упавший консьюмер догоняет, не тормозя граф); **обработка состояния** в стрим-процессинге = локальная таблица + журнал, восстанавливаемая из changelog. Инженерная иллюстрация — Kafka: **partition = упорядоченный лог**, глобального порядка нет (вместо него порядок по ключу + стеновые часы в сообщениях); порядок в partition — гарантия для одного сендера; батчинг на всех уровнях + бинарный формат без перекодировки (валидность «одно и то же» в памяти, на диске и в сети) дают запись/чтение на скорости диска; **log compaction** (retention-обрезка по ключу) вместо полного удаления сохраняет «полную резервную копию» системы. Масштаб на тот момент: **60 млрд сообщений в день** через Kafka, 75TB на ДЦ — «лог может быть дешёвой репликой в виде линейного ввода-вывода на больших HDD, в отличие от serving-слоёв в RAM/SSD». Отсюда паттерн **«лог + serving layer»**: запись идёт в лог (источник правды), serving-ноды (разные индексы: btree/sstable/inverted) подписываются и применяют изменения; read-your-writes через таймстамп — дождаться, пока нода проиндексирует до нужной позиции; восстановление ноды = перемотка лога.

**Что брать на секцию.**
- **«Лог = время»**: одна фраза «все изменения системы — это лог; таблицы и кэши — производные проекции» сразу поднимает ответ по хранению (медиа-объекты), очередям (fan-out) и CDC (как синхронизировать кэш и поиск). Маркер: «state machine replication: одинаковые входы в одинаковом порядке → одинаковое состояние».
- Двойственность таблиц/логов даёт готовую связку компонентов схемы: postgres (таблица) → WAL/binlog (лог) → Kafka (лог) → кэш/поиск/аналитика — «один источник правды, N проекций».
- Для блока очередей (бриф 07): «очередь — это лог с позицией консьюмера», «консьюмеры читают в своём темпе, лог — буфер», «порядок гарантируется внутри partition, не глобально» — аналог гарантий Kafka.
- Read-your-writes по таймстампу лога — конкретная механика, которой можно ответить на «как обеспечить свежесть при чтении из кэша/реплики без master-чтений» (перекликается с critical reads TAO из 45.30).

### 3.2 Transactional Outbox (+ Sagas) — атомарный «запись + событие»

**Выжимка.** Классическая проблема: сервис обновляет бизнес-сущность и должен опубликовать событие (сосед map-структуры: счётчик лайков → запись события «лайк» для ленты/аналитики). 2PC между БД и брокером не годится: не все брокеры/БД его поддерживают, а связывание сервиса и с 2PC-координатором — антипаттерн. Наивные варианты ломаются: отправить **внутри** транзакции — событие улетит при откате; отправить **после** коммита — сервис может упасть между коммитом и отправкой; плюс нужен порядок сообщений. **Решение (Transactional Outbox)**: сообщение пишется в ту же транзакцию, что и бизнес-данные — в таблицу outbox (в NoSQL — поле записи); отдельный **Message relay** (CDC-подобный процесс: Transactional log tailing или polling publisher) читает outbox и отправляет в брокер. Гарантии: сообщение отправлено **тогда и только тогда, когда транзакция закоммичена**; порядок = порядок коммитов. Ограничение: relay может опубликовать сообщение дважды (упал после публикации до отметки) — поэтому **консьюмер обязан быть идемпотентным** (по ID сообщения); обычно брокеры и так доставляют ≥1 раза, так что это стандартное требование, а не новая сложность. Два способа реализовать relay: **transactional log tailing** (читать binlog/WAL — Facebook/Netflix так и делают) и **polling publisher** (периодический SELECT по outbox). Спутник паттерна — **SAGAS** (Garcia-Molina & Salem, Cornell): цепочка локальных транзакций с компенсациями вместо глобальной; каждая шаг-транзакция публикует событие, следующая шаг-транзакция инициируется потребителем события (или оркестратором).

**Что брать на секцию.**
- Прямой ответ «как атомарно записать и опубликовать событие»: «2PC с брокером не делаем — пишем событие в outbox той же транзакцией, relay отправляет; консьюмеры идемпотентны». Это закрывает «минус» из вопроса про очередь: «откуда гарантия, что событие не потеряно/не задублировано».
- В нашей схеме Instagram/Twitter это лайки/посты → событие в fan-out: «лайк записан, событие — в том же коммите в outbox, worker читает outbox и доставляет в ленты (fan-out)» — одной фразой связываются бриф 07 и классический design.
- CDC-формулировка: «outbox читаем транзакционным tailing'ом (binlog), а не опросом» — стыкуется с CacheFront (3.3) и DBLog (второй эшелон): один приём в трёх источниках.
- Sagas — готовый ответ на «как сделать распределённую транзакцию без 2PC» (KB §7): цепочка локальных транзакций + компенсации; события — как двигатель саги.

### 3.3 Uber CacheFront — 40M RPS через интегрированный кэш внутри движка БД

**Выжимка.** Docstore (Uber) — распределённая БД на MySQL (хранилища в движке: partition = 1 leader + 2 follower, Raft; сверху stateless query engine: планировщик, роутинг, шардирование). Проблема: лимит скорости чтения с диска, вертикальное/горизонтальное масштабирование дорого («стоимость ×6 на 3 stateful-ноды в 2 регионах»), hot keys не решаются шардированием; в довесок один use case требовал настолько больше чтений, что MySQL-ноды физически не справлялись. Разрозненный кэш (каждая команда свой Redis + своя инвалидация) — источник зла, поэтому сделали **CacheFront — встроенный кэш в query engine** (cache-aside): чтение → Redis, miss → storage engine, ответ стримится, пропущенное асинхронно заполняет Redis. Четыре инженерные детали: **1) CDC-инвалидация (Flux)** — binlog-стрим Docstore → консьюмер, который invalidate/upsert'ит строки в Redis; сделало консистентность «секунды вместо TTL-минут», TTL остался защитой по умолчанию (5 мин); «binlog не пускает в кэш незакоммиченные транзакции». **2) Дедупликация записи в кэш** — read path и write path пишут в Redis одновременно, риск перезатереть свежее стейлом: Lua-скрипт (EVAL) на сервере Redis сравнивает timestamp-версию строки из MySQL и пишет только новее — атомарно, одно обращение. Точковые записи получили более сильную гарантию: query engine по API умеет инвалидировать кэш синхронно после записи (read-own-writes); условные массовые update — только через Flux (eventual). **3) Cold cache при region failover** — активный-активный, кэш должен быть тёплым в обеих регионах; вместо cross-region репликации значений Redis (два механизма репликации → риск рассинхрона) — **replicate keys**: в удалённом регионе на ключ просто делается read request к query engine, который при miss читает БД и пишет кэш сам (значение всегда консистентно БД своего региона, рабочий набор строк одинаков, трафик межрегиона ограничен). **4) Устойчивость самого кэша** — negative caching (несуществующие строки кэшируются флагом — ноль походов в БД), несколько Redis-кластеров на один instance, **шардирование Redis по partition key, отличное от шардирования БД** (падение одного Redis-кластера не уронило один шард БД, а распределилось по всем), sliding-window circuit breaker на ноду Redis (short circuit пропорционально ошибкам), **адаптивные таймауты** — timeout Redis = P99.99 латентности кэша, хвост режется, DB обслуживает только 0.01%. Результаты: P75 −75%, P99.9 −67%; здоровье: **сравнение кэша и БД в shadow-режиме** (сверка при чтениях; кэш 99.99% консистентен); кейс с 6M RPS: было бы ~60K CPU-ядер на storage engine → стало ~3K Redis-ядер при 99.9% hit; сегодня **>40M RPS с кэша во всех инстансах**.

**Что брать на секцию.**
- Отличие от уже пройденных кэш-кейсов: FB/Memcached и Twitter/Redis — **отдельные кэш-слои, о которых думает сервис**; CacheFront — **кэш как внутренность движка БД** (клиент ничего не знает). Готовая фраза на «как снизить нагрузку на БД»: «кэш прячем внутрь шлюза БД: cache-aside + инвалидация через CDC, а не через бизнес-код».
- **CDC-инвалидация + Lua-дедупликация по версии** = ответ на извечный «как инвалидировать кэш» (KB §4): не TTL и не ручная инвалидация в бизнес-логике (она не покрывает условные update), а подписка на поток изменений. Идемпотентный upsert с версией на сервере Redis — конкретика, которой обычно нет у кандидатов.
- **Negative caching** (в TAO из 45.30 то же самое: кэшированный «0») — теперь двумя компаниями; устойчивая деталь для схемы «поиск/профиль».
- Circuit breaker на кэш-ноду + **адаптивные таймауты от перцентиля** — продолжение линии 45.30 (Netflix: таймауты от p99.5) на практике; «таймаут = p99.99 кэша, хвост отдаём базе» — сильная однострочная формула.
- Cross-region: **реплицируем ключи, а не значения** (read-triggered warming) — неочевидное решение для multi-region кэша в active-active (стыкуется с DNS GSLB 3.5: «холодный кэш при failover = каскад в БД»).

### 3.4 LSM-tree (O'Neil et al., 1996) — почему write-heavy хранилища не на B+tree

**Выжимка.** Мотивация статьи — классика insert-heavy нагрузки (TPC-A-подобная History-таблица, где нужен индекс по account-id в реальном времени): **B-tree на этом убивает — каждый вставленный индекс поддерживается в реальном времени, что удваивает I/O стоимость транзакции и увеличивает суммарную стоимость системы до 50%**. Идея LSM-tree: **откладывать и батчить изменения индекса, каскадно перетекая из memory-компонента через один или несколько disk-компонентов, «в духе merge sort»**. Многоуровневость: **C0 в памяти** (маленький, вставки дёшевы и последовательны), **C1 на диске** — как только C0 достигает порога, запускается **rolling merge**: из C0 вырезается сегмент и сливается в C1; C1 устроен как B-tree, но **оптимизирован под последовательный доступ: узлы 100% заполнены, последовательности одностраничных узлов упакованы в непрерывные многопейджевые блоки для эффективной работы головок диска** (то же, что потом назвали SSTables). Во время слияния все значения **непрерывно доступны** для чтения (через C0 или компоненты на диске, короткие блокировки). Стоимость: вставка амортизируется (дешёвые последовательные записи вместо случайных); плата — **чтение дороже**: искомое значение может лежать в любом из уровней (отсюда блумфильтры, перекрывающиеся уровни, compaction в более новых системах). Для интервью дальше хватает уровня названий: SSTable = отсортированная таблица (неизменяемые файлы), **compaction** = слияние уровней (size-tiered vs leveled — Scylla wiki), блумфильтр на уровне — ускоритель отрицательных чтений; Dynamo/Cassandra/RocksDB/HBase — LSM-семейство, это и есть ответ «что под капотом у нашего NoSQL».

**Что брать на секцию.**
- Одна фраза-маркер уровня «внутри»: «write-heavy хранилище — это LSM: вставки батчатся в памяти и каскадно сливаются на диск последовательными записями; за это платим более дорогим чтением (уровни + блумфильтры)». Противовес B+tree PostgreSQL — знание **почему выбор разный** — выигрышно на уточняющих вопросах брифа 04–05.
- Трейдофф «insert I/O vs read path» — естественный ход линейки ответов: «это write-heavy или read-heavy?» → выбор хранилища. Стыкуется с KB §5–§6 и 45.19 (B+tree из Architecture Notes).
- Lucene/RocksDB/Cassandra/Scylla — примеры «используют LSM и compaction»; упоминание Twitter/Instagram-масштабов (Cassandra у Twitter, RocksDB у многих) звучит как опыт.

### 3.5 DNS и GSLB: Page of Shame (2004) + Shopify (2023) — глобальный слой отказоустойчивости

**Выжимка.** Tenereillo (классика, не устарела): GSLB-устройства (DNS-ответ «какой датацентр») **не дают HA для браузерных клиентов**, потому что ответы DNS кэшируются в двух местах, которые нельзя контролировать: **browser DNS cache** (IE — 30 минут, Netscape — 15; не видит TTL, т.к. gethostbyname() не возвращает TTL) и **resolver-кэш ISP**. Сценарий: спал основной сайт → GSLB мгновенно отдаёт IP резерва новым запросам, но уже подключённые клиенты **до получаса** стучатся в мёртвый IP из браузерного кэша — «супернавороченный health check не помогает». Единственное решение для браузерного HA — **несколько A-записей** (DNS-протокол задуман для этого): клиент тихо пробует следующий IP. Но **мульти-A убивает детерминированный выбор сайта**: порядок A-записей **переупорядочивается** резолвером (BIND: первая случайная, остальные циклически; Windows XP кэш — subnet-adjacent первым), значит GSLB-фичи (active-standby, RTT/footrace, geo, persistence) не работают. Site-куки не спасают: после повторного резолва клиент попадает в другой ДЦ, редирект требует site-уникальный FQDN (www-a.trapster.net), а на этот адрес пользователи делают закладки — и для него тоже нужны несколько A-записей. Вывод: **выбор «детерминированный GSLB» vs «HA» — взаимоисключающий**; BGP host route injection (anycast-подобный) как альтернатива редко работает (convergence > 5 минут, bogon-фильтры, route maps). Плюс: возвращать A-записи обоих сайтов даже при health check'е — многие отказы транзиентны (прокатилась волна DoS/вируса/питания). Shopify (2023) — современная практика: TTL — рычаг (низкий TTL = часто повторные резолвы = точность, но +1с разрешения каждые 15с = 1ч36м в день; TTL 60с = 24м/день), резолверы иногда игнорируют/перекрывают TTL; 4 use case DNS-трафикменеджмента: **active-passive failover** (переключение на резервный кластер, снимает давление с on-call), **active-active share** (проценты трафика по DNS-ответам; важно при вендорах с минимальным commitment'ом), **green-blue progressive rollout** (переливать проценты трафика на новую версию), **гео-регионализация** (ответ по локации клиента). У них система автоматизирована: >40 доменов, >12 команд, >100M запросов/24ч.

**Что брать на секцию.**
- Лишний слой для «отказоустойчивости»: кандидаты обычно останавливаются на multi-AZ/ReplicaSet; **«а глобально?»** — DNS-слой: TTL, браузерный кэш, мульти-A. Фраза-маркер: «DNS — это не мгновенный failover: браузерный кэш не видит TTL и держит мёртвый IP до 30 минут; HA для браузеров = несколько A-записей, а не «умный» GSLB» (+site-куки/redirect как ком промисс сессий).
- Трейдофф TTL: «точность vs стоимость резолва» с числами Shopify (15с TTL = 1ч36м/день дополнительного резолва) — конкретика с числами, как в KB §9-стиле.
- Те же паттерны, что «внутри» (circuit breaker, active-passive/active-active, canary) — на сетевом слое; красиво замыкает: DNS — ещё один вход графа деградации (стыкуется с retry storm KB §9: клиенты с закэшированным IP = traffic к мёртвой цели).
- Вопрос «а как же облачные anycast/GSLB»: Page of Shame объясняет, почему это работает только до первого соединения — за мгновенный уровень отвечают anycast-сети и L4-балансировщики, а не DNS.

## 4. Второй эшелон

| Материал | Что даёт | Когда |
|---|---|---|
| [Netflix DBLog — Change Data Capture framework](https://netflixtechblog.com/dblog-a-generic-change-data-capture-framework-69351fb9099b) | Linked-list подход к CDC (обход binlog-парсинга), один из двух канонов relay для outbox | уточняющий вопрос про CDC/синхронизацию кэша (бриф 07) |
| [Facebook Gorilla (VLDB 2015, PDF)](http://www.vldb.org/pvldb/vol8/p1816-teller.pdf) | In-memory сжатие time series (XOR-кодирование) — база всех метрик | вопрос про наблюдаемость/метрики (KB §10) |
| [Airbnb: Avoiding Double Payments](https://medium.com/airbnb-engineering/avoiding-double-payments-in-a-distributed-payments-system-2981f6b070bb) | Идемпотентность в платежах: read/write/async repair, idempotency keys (статья member-only — прочитан тизер; паттерн идемпотентности знать обязательно) | деньги/повторные события в асинхронщине (KB §7; пользователю близко как финтек-кейс) |
| [DB as queue Antipattern (4 ссылки: Wiki, SO, Hadlow, CloudAMQP)](https://en.wikipedia.org/wiki/Database-as-IPC) | Почему БД — не очередь: атомарность «запись-и-читай» нет, поллинг, удаление строк, стоимость | вопрос «а можно Postgres вместо Kafka» (бриф 07) |
| [BigTable (OSDI'06)](https://static.googleusercontent.com/media/research.google.com/en//archive/bigtable-osdi06.pdf) + [Dynamo (SOSP'07)](https://www.allthingsdistributed.com/2007/10/amazons_dynamo.html) | Первоисточники по хранилищам (KB §5 уже пересказывает) | глубина по требованию «назовите оригинал» |
| [Scalable System Design Patterns (horicky, 2010)](http://horicky.blogspot.com/2010/10/scalable-system-design-patterns.html) | Классические паттерны в одном месте: load-balancing options, cache-cue, write-master/read-replicas, sharding by function/entity/… | референс-чеклист перед секцией |
| [Operational Transformation (codecommit)](http://www.codecommit.com/blog/java/understanding-and-applying-operational-transformation) + Google Docs видео | Коллаборативное редактирование — классический вопрос «не из брифа» | если спросят real-time collab (маловероятно на этапе 2) |
| [Netflix Active-Active for multi-regional resiliency](https://netflixtechblog.com/active-active-for-multi-regional-resiliency-c47719f6685b) | Мульти-регион как продукт: фундамент для разговора про региональную деградацию | продолжение 3.5 / бриф 08 |
| [Google Subsetting Algorithm (ACM Queue)](https://queue.acm.org/detail.cfm?id=3570937) + [Netflix Zuul connection churn](https://netflixtechblog.com/curbing-connection-churn-in-zuul-2feb273a3598) | Как без «все × все» балансировать целевую нагрузку | уточняющий вопрос про pool/LB |
| [Jeff Dean: Stanford 295 / Design of Computer Systems (+ Capacity Estimation)](https://www.youtube.com/watch?v=modXC5IWTJI) | Бэк-оф-энvelope от автора чисел | числа уже закрыты KB §1/45.25 — исторический контекст |
| [Google S2 geometry / Hilbert curve](https://blog.christianperone.com/2015/08/googles-s2-geometry-on-the-sphere-cells-and-hilbert-curve/) | Геопространственное шардирование (аналог geohash) | вне брифа; «Uber/гео» — если спросят |
| Alerts/Anomaly (Uber Argos, LinkedIn ThirdEye, Isolation Forest) | Наблюдаемость уровня «аномалии» | KB §10, эксплуатация; не для секции |

## 5. Как использовать

1. **Топ-5 — это «второй слой» под компоненты из 45.30**: к каждой схеме ответа добавляется одна фраза «а внутри это работает так». Не учить заново — иметь маркеры: «лог = время; таблицы — проекции» (3.1), «событие пишем в outbox той же транзакцией, консьюмеры идемпотентны» (3.2), «кэш инвалидируем через CDC, не TTL» (3.3), «write-heavy — LSM: батч в память, каскадное слияние» (3.4), «глобальный failover — не “умный DNS”, а мульти-A и TTL-трейдофф» (3.5).
2. **На секцию 18.09 это P3 — не открывать новое.** Конспект написан так, чтобы его можно было пробежать за 20 минут утром слота (5 блоков × ~4 строки маркеров). Глубина (первоисточники 3.4, трейдоффы 3.5) — для следующих секций и этапов.
3. Чего в репо **нет**: учебной теории, шпаргалок, разборов формата — идти в `../methodology.md`, `../classic-designs.md`, `lsd-polomodov-guide.md`, `lsd-leetcode-template.md`.
4. При бритье ссылок: `jenpsen.io` в README — опечатка, правильный адрес `jepsen.io` (материал 33, TASK-45.37).

## Связанные документы

- `../knowledge-base.md` — §3 (сеть/DNS), §4 (кэш), §5 (хранилища), §6 (шардирование/LSM), §7 (консистентность/транзакции), §8 (очереди/потоки), §9 (отказоустойчивость), §10 (эксплуатация)
- `../classic-designs.md` — §2 (лента: fan-out → outbox-связка), §7 (эталонные схемы)
- `lsd-awesome-scalability.md` — материал 26: компоненты схемы (ID, соцграф, кэш, деградация) — этот конспект даёт их «внутренности»
- `lsd-architecture-notes.md` — материал 15: B+tree и индексы (противовес LSM), Redis-топологии
- `learn-system-design-index.md` — индекс подборки (этот материал — №27, Advanced, P3)