title: Конспект источника 1 — К. Кардаманов «Как проходят архитектурные секции собеседования в Яндексе» (habr 564132) source: https://habr.com/ru/company/yandex/blog/564132/ author: Костя Кардаманов, отдел технологий разработки Яндекса конспект: подготовлено 2026-09-17, TASK-45.5; это первоисточник формата секции — каркас для methodology.md (TASK-45.2) и эталонного разбора classic-designs.md §1 (TASK-45.3) статус: официальный текст Яндекса о формате; числа и решения — дословно из статьи
Источник 1: статья Яндекса о практике дизайна распределённых систем (habr 564132)
Единственный официальный первоисточник формата нашей секции: автор проводит такие интервью сам. Всё, что в methodology.md названо «6 этапов», и весь эталонный разбор URL shortener в classic-designs.md §1 выросли отсюда. Конспект — выжимка статьи с расчётами; читать до тренировок по §1 URL shortener.
1. Формат секции: что сказал интервьюер
- Секция по дизайну систем назначается кандидатам уровня senior+ (кодовая секция — всем). Проверяется не «минимум» (код), а достаточность навыков: способность разработать сложную систему целиком.
- Задание — спроектировать сложную, высоконагруженную и отказоустойчивую систему; за основу берут реально существующую (пример статьи — Яндекс Go).
- Кандидат — основной участник беседы, интервьюер играет второстепенную роль и перехватывает инициативу только в крайних случаях. Молчать и ждать вопросов — проигрышный сценарий.
- План беседы и критерии оценки «достаточно просты» — автор прямо советует запомнить план и придерживаться его в процессе.
2. План секции: 5 основных блоков + дополнительные вопросы
| # | Этап (формулировка статьи) | Что делать |
|---|---|---|
| 1 | Уточнение задачи: формализация требований, оценка аудитории, порядок нагрузки | Вытянуть числа вопросами; выделить функциональные и ключевые нефункциональные требования (время ответа, доступность, согласованность); записывать требования, чтобы не потерять к концу беседы |
| 2 | Потоки данных, API, основные блоки | Что входит и что выходит; из этого — программный интерфейс и состав основных сервисов. Выписать сущности и сигнатуры базовых API-методов |
| 3 | Детальная схема: компоненты и их роли, устройство самой важной части, структура БД | Концептуальная модель данных; найти самые нагруженные компоненты; алгоритмы/псевдокод для самого сложного места. Сбалансированность сложности: готовое решение вместо самописного |
| 4 | Оценка вычислительных ресурсов, поиск узких мест | CPU/память/диск/сеть на компонент; latency numbers вспомнить обязательно. Не хватает вертикали — менять алгоритм/структуру данных или горизонтально масштабироваться (второе «обычно выигрышнее в долгосрочной перспективе», цена — сложность и эксплуатация) |
| 5 | Топология и эксплуатация: балансировка, отказы, мониторинг, обслуживание, экстремальные условия | ДЦ/CDN/кэширование; переживание отказа сервера и ДЦ; план на критическую ошибку в проде и на превышение нагрузки в разы/порядки (чем жертвуем для выживания); обновления и смены схемы данных; в конце — вернуться к требованиям из этапа 1 и показать, как контролировать их метриками |
| + | Дополнительные вопросы (если осталось время) | Устройство фреймворков/БД/алгоритмов; качество сервиса глазами пользователя; тестовые контуры, rolling releases, CD; версионирование данных; отладка в работающем кластере |
Соответствие методичке: этапы 1–5 = §1 methodology.md (тайминг 8/7/5/18/7/10 мин); блок «доп. вопросы» в 60-минутном слоте обычно не достигается — это буфер.
3. Что оценивается (критерии, разбросанные по тексту)
Отдельного чек-листа в статье нет, но интервьюер называет измерения, по которым судит о senior-кандидате:
- Формализация требований и оценка аудитории/нагрузки до любой схемы.
- Гипотезы при нехватке данных: «выдвигать обоснованные гипотезы можно и нужно» — на основе известного (население планеты, доля интернета). Ступор от отсутствия цифр — минус.
- Знание классов хранилищ и их свойств: «нам важнее свойства и предоставляемые системой гарантии, чем конкретное название» (пример: Memcached для персистентных данных — ошибка; Redis на терабайты редкоменяемых данных — сомнение). Знать класс KVS и его представителей (Aerospike, Redis, Couchbase, Memcached, HBase), чтобы «делать разумный выбор».
- Минимальная сложность и стоимость (KISS): «система должна быть минимально сложной и дешёвой в разработке и эксплуатации»; готовое решение вместо собственной разработки, «не усложняйте без лишней необходимости».
- Оценка ресурсов и узких мест: расчёты от характеристик железа и latency numbers; понимание «бутылочного горлышка».
- Сценарии отказов и меры предотвращения — прямая ответственность разработчика; эксплуатация/HA как область знаний (SRE).
- Метрики: подход metrics first — «сначала определить или построить метрику, которую улучшаете, и только затем менять систему»; метрики — и работоспособность в моменте, и основа ретроспективного анализа планов.
- Видение системы в 4 измерениях: компоненты и связи сейчас + выдерживаемая нагрузка сейчас + развитие на годы вперёд (замена компонентов, рост данных, будущее горлышко) + причины отказа.
- Ясно и аргументированно выражать мнение — решения обсуждаются командой; одиночных архитекторов уровня крупных систем не бывает.
4. Эталонная задача: URL shortener (500k RPS, 1 млрд ссылок)
Условие: высоконагруженная система сокращения URL для компании масштаба Facebook, бесплатная и платная версии; платная не ограничивает RPS/число ссылок/TTL и даёт более короткие ссылки.
4.1 Этап 1 — диалог с числами (учить наизусть)
| Вопрос кандидата | Ответ |
|---|---|
| Объём переходов по ссылкам? | 500 тыс. RPS в пике |
| HTTP или HTTPS? | Оба, преимущественно HTTPS |
| Сколько ссылок в базе? | 1 млрд всего, у платных — 1 млн |
| Сколько аккаунтов? | Сотни тысяч бесплатных, тысячи платных |
| Скорость ответа? | 150 мс для 95 % запросов на чтение |
| Доступность? | Четыре девятки на чтение |
| Согласованность? | Новые ссылки — строго согласованы; модификация существующих — допускается чтение неактуальных несколько секунд |
| Лимит бесплатного аккаунта? | 1000 запросов/мин |
| Новые ссылки? | Сотни тысяч в день |
| Анонимные ссылки? | В базовой версии — не реализуем; в расширенной — «можно подумать» (ограничения на добросовестное использование) |
Производные: ≈10–20 RPS записи против 500k RPS чтения → дизайн про чтение; «строго для новых» + eventual для правок → двухуровневое хранение с путём согласованности для новых ссылок.
4.2 Этап 2 — блоки и API
- Control plane — управление аккаунтом и ссылками: авторизация, управление аккаунтом, статистика по ссылкам, поиск/модификация/удаление. REST — сразу и для веб-UI, и для сторонних систем. Нагрузка — единицы RPS, «на дизайн системы в целом не повлияет».
- Data plane — переход по ссылке:
GET /{id}→ HTTP 302. - Кодирование идентификаторов: генерация random (исключить перебор). 1 млрд ≈ 2^30 → 32 бита; base36 (36 символов): 36^6 ≈ 2.2 млрд → 6 символов, «+1 разряд для исключения перебора» → 7. Платные: 1 млн ≈ 2^20 → 36^4 ≈ 1.7 млн → 4+1 = 5 символов.
4.3 Этап 3 — детали, БД, синхронизация
Хранение (источник правды): любая реляционная СУБД, две таблицы:
Account(account_id, login, type)— сотни тысяч записей, десятки байт/запись → единицы МБ.Link(link_id, account_id, ttl, created, accessed, url)— 1 млрд записей, сотни байт/запись → сотни ГБ.
Запись ~10–20 RPS (хватит одного сервера), чтение заведомо выше одного сервера. Managed-СУБД, объём без шардирования, схема primary + hot standby; между равнозначными веб-серверами — транзакции против race condition.
Синхронизация с KV: при любом изменении Link — репликация в KV store; альтернатива — собственная репликация через таблицу журнализации Oplog(id, link_id, account_id, optime, url); «применение журнала и отставание реплик — тема доп. вопросов».
Вместо 2PC — majority-коммит: двухуровневое хранение повышает сложность → проблема «записалось в одно, не записалось в другое». 2PC дорог → коммитить в СУБД после подтверждения записи от большинства реплик KV; мусор в KV от непрошедших коммитов чистит фоновая сборка мусора.
Read-контур (data plane): несколько HTTP-серверов + собственный модуль выдачи и rate-limit; балансировка DNS или L3 IPVS round robin + health checks. Алгоритм обработки запроса:
- По ID из KV store (read-only зеркало:
link_id → {url, account_id}) получить URL и владельца. - Проверить лимит аккаунта по read-only-таблице
account_id → RPSв разделяемой памяти, которую раз в секунду обновляет отдельный процесс (сотни тысяч ключей × 4–6 байт, сортированный список, единицы МБ). Превышение → HTTP 429. - Регистрация обращения — асинхронно: счётчики аккаунтов (
account_id → counter) копятся в памяти воркера и раз в секунду уходят в RPS limiter; ID затронутых ссылок копятся в set и раз в минуту уходят в очередь.
KV store: пары link_id → {url, account_id}, ~100 тыс. RPS на сервер, данные ~сотни ГБ (100 байт/ссылка), CPU почти не тратится → не шардировать, а реплицировать. Чтение с secondary, которые отстают → путь согласованности новых ссылок: L1 LRU-кэш на веб-сервере — промаха мимо KV (L2) → поход в центральную СУБД → ответ кэшируется в L1 (ограничивает нагрузку на СУБД).
LAT actuator (актуализация времени доступа): сервисный процесс забирает из очереди (multiple producers, single consumer — реализована на том же KV) накопленные множества, сливает и делает UPDATE Link SET accessed = now() WHERE link_id IN (...). Отказоустойчивость: несколько равнозначных процессов, на каждой итерации захват служебной записи SELECT ... FOR UPDATE.
RPS limiter: выбор «отдельный gRPC-сервис vs состояние в основной СУБД» — по принципу минимизации расходов при приемлемом качестве и рисках. Выбрано: состояние в центральной базе + асинхронная актуализация. Плюсы: нет отдельного сервиса с репликацией/консенсусом; состояние персистентно и согласовано. Минусы и их адресация: задержка актуализации (единицы секунд — приемлемо); риск отказа data plane при перевыборах primary → воркеры работают по снимку из разделяемой памяти; риск перегрузки СУБД → никакой прямой записи из data plane в СУБД, всё через распределённую очередь. Механика:
RPSLimit(account_id, balance, limit)— тысячи записей (окно квотирования короткое, нулевые записи исключаются) → снимок ~полмегабайта.- Лучше:
RPSLimitSnapshot(data BYTEA)— полный снимок, сериализованный в бинарный формат (protobuf) со сжатием → на порядок меньше данных, можно чаще; воркеры забирают полное состояние раз в ~100 мс. - Алгоритм — leaky bucket: события вычитают ёмкость корзины, раз в квант корзина доливается; полная корзина (balance = limit) — запись удаляется из состояния. Бонус — burst budget (кратковременное превышение лимита).
Фоновые процессы: поиск и удаление ссылок с истёкшим TTL, сборка мусора от незавершённых транзакций; запуск по таймеру с захватом блокировки.
4.4 Этап 4 — оценка ресурсов (считаем от дефицитного ресурса)
- Data plane: дефицитный ресурс — CPU: HTTPS дороже plain HTTP на порядок (handshake, несмотря на session reuse и аппаратные инструкции) → ~20 тыс. RPS на воркер. KV store (100k RPS) CPU не тратит → ставить инстанс KV рядом с каждым веб-сервером: память сервера утилизируется, сетевая подсистема разгружается, надёжность выше. Итого 25 воркеров на 500k RPS.
- Отказоустойчивость: консенсуса в контуре нет, число регионов не важно; сервис должен переживать отказ целого региона и сохранять 25 работоспособных воркеров → 9 серверов × 4 ДЦ (запас на обновление/отказ до двух воркеров при недоступном регионе) + 4 IPVS (по числу ДЦ — не удлинять маршрут за пределы ДЦ) + 3 сервера СУБД (консенсус для автопереключения primary). Итого 43 сервера.
- Время ответа: пинг NY–Москва ~120 мс → на ответ сервера остаётся ~30 мс из 150. Воркер: KV на localhost — единицы мс + сервер — единицы мс + маршрутизация в ДЦ — сотни мкс → ≤10 мс, большой запас → географическое распределение дополнительно не нужно.
- Control plane: единицы CPU, несколько локаций; СУБД — доминирует диск (~десяток CPU), полноценный сервер.
4.5 Этап 5 — топология и эксплуатация
Балансировка на всех уровнях — round robin, нагрузка равномерная.
Сценарии отказов (проговаривать по каждому компоненту):
| Отказ | Эффект и реакция |
|---|---|
| IPVS-балансировщик | Нагрузка на оставшиеся 3, многократный запас |
| Веб-сервер / KV store | Размазывается по 8 соседям в ДЦ; при пиковой нагрузке держим 6 воркеров в ДЦ — иначе исключаем ДЦ из балансировки |
| Secondary СУБД | Не влияет |
| Primary СУБД | Влияет на control plane, не влияет на GET |
| RPS limiter и вспомогательные | Основные функции работают, риски растут |
Защита от превышения нагрузки на чтение: короткие пики — запасом по времени ответа (очередь на воркерах); детект подозрительного трафика на IPVS (хосты/подсети, blacklist от воркеров); blacklist за одинаковые/несуществующие ссылки; понижение криптостойкости SSL.
Мониторинг: агрегация по классам серверов (primary/secondary СУБД, KV, веб-сервер, IPVS, RPS limiter, вспомогательные); ресурсы (CPU/RAM/disk IO/net IO) по серверам и процессам; количество и время обработки запросов по квантилям; коды ответов с защитой от шума (частые несуществующие ссылки, аккаунты с исчерпанной квотой).
Логи и трассировка: логи веб-серверов при таких объёмах дороги и сами влияют на производительность → писать на SSD/NVMe, часто ротировать, сжимать, перекладывать в дешёвое хранилище (первый уровень — HDD на том же сервере); уровни избыточности по возрасту архива; отладочная трассировка — каждый k-й запрос и/или по флагу в запросе.
Обновление: воркеры независимы, теряем до 3 в ДЦ без потери качества → катим по 3 воркера, ДЦ строго последовательно, сравнивая метрики с остальными. Тестовый контур меньшего размера с репликой, куда дублируется каждый k-й продовый запрос. СУБД — обновление с коротким даунтаймом после проверки на тестовом контуре (чтение не страдает).
Доп. вопросы (если осталось время): устройство выбранных фреймворков/БД/алгоритмов; качество сервиса с точки зрения пользователя; локализация/персонализация; тестовые контуры, rolling releases, CD; версионирование данных; быстрые срезы данных под экстремальную нагрузку; поиск проблем и отладка в работающем кластере.
5. Принципы статьи (звучат как критерии оценки)
- KISS / минимальная сложность: система минимально сложна и дешёва в разработке и эксплуатации; готовое вместо самописного; «не усложняйте без лишней необходимости».
- Metrics first: сначала метрика, которую улучшаем, потом изменение системы; метрики — инструмент и моментального контроля, и ретроспективы.
- Гипотезы при нехватке данных: обоснованная гипотеза вместо ступора; данные вытягиваем вопросами, требования записываем.
- Гарантии важнее названий: выбирать по свойствам и гарантиям хранилища, а не по бренду; знать представителей каждого класса.
- Разделение control plane / data plane: управление (единицы RPS, REST, любая СУБД) отдельно от горячего пути чтения (500k RPS, 302, никаких тяжёлых синхронных зависимостей); общий пул балансировщиков — отказ data plane не валит control plane.
- Majority-коммит вместо 2PC при двухуровневом хранении + фоновая GC для мусора; согласованность «строго для новых» — отдельным путём (L1-кэш мимо отстающих реплик).
- Асинхронная актуализация всего, что вне критического пути: accessed (очередь + батч-UPDATE), счётчики RPS (память воркера → очередь → лимитер), лимиты воркером — из снимка в разделяемой памяти. Общий рефрен: «такой способ увеличит критический путь».
- Сценарии отказов и мониторинг: по каждому компоненту — что будет при отказе и как это видно; квантили, шумоподавление; план на ошибку в проде и на экстремальную нагрузку (чем жертвуем).
- Ресурсы от дефицитного ресурса: TLS→CPU→20k RPS/воркер; ко-локация компонентов по взаимодополняющим ресурсам (CPU веб-сервера + память KV на одной ноде); запас — сценариями (9×4), не «лишними серверами».
- Видение в 4 измерениях: сейчас + нагрузка + развитие на годы + причины отказов; горизонтальное масштабирование «выигрышнее в долгосрочной перспективе».
- Инженерная коммуникация: ясно, чётко, аргументированно; умение объяснить решение — часть работы senior/архитектора.
6. Рекомендации статьи по подготовке
- Освежить литературу и доклады о дизайне реальных систем: Таненбаум «Распределённые системы», Бёрнс «Паттерны проектирования распределённых систем», Kleppmann DDIA, Google SRE; доклады HighLoad++.
- The System Design Primer — «отличная методичка», но без теоретической базы легко запутаться (в нашем плане — источники 2–3).
- Практика: взять сложную систему (хранилище, видеохостинг, поиск, лента, мессенджер, обработка заказов) и прогнать по плану на доске/листе; ideally — с слушателем-разработчиком. Совпадает с нашим протоколом тренировок
methodology.md§6. - Курсы System Design Interview автор не рекомендует (платные, качество решений низкое).
7. Пересечения с эталонными разборами (classic-designs.md, TASK-45.3) и методичкой
Конспект — первоисточник; в производных документах он уже разложен так:
| Материал статьи | Где живёт в наших материалах |
|---|---|
| 6-блочный план секции + рекомендация «запомнить и придерживаться» | methodology.md §1 (этапы с таймингом) и §2 (фреймворк ответа по этапам) |
| Диалог-вытягивание требований (таблица чисел §4.1) | classic-designs.md §1 «Этап 1. Требования» — дословно та же таблица вопросов и ответов |
| Разбор URL shortener целиком (блоки, БД, majority-коммит, RPS limiter, LAT actuator, ресурсы 25/9×4/43, эксплуатация) | classic-designs.md §1 «URL shortener — эталон Яндекса» — полный конспект решения по 6 этапам |
| Принципы §5 этого конспекта | classic-designs.md §1 «Чему учит эталон» (6 паттернов) и methodology.md §3 (речевые паттерны: гипотеза, трейдофф, гарантии вместо брендов, KISS, критический путь, metrics first, чекпоинты) |
| Типовые ошибки (молчание, усложнение, синхронный критический путь…) | methodology.md §4 «Топ-10 ошибок» — выведены из антипримеров статьи |
| Список литературы статьи (DDIA, SRE, Primer) | methodology.md §5 порядок чтения и knowledge-base.md §12 (карта DDIA) |
Практический вывод: URL shortener из этой статьи — вероятный формат и эталон нашей секции (HR дал её первой в списке материалов). Тренировочный приоритет: URL shortener → лента новостей (заявленный фокус секции «инстаграм/твиттер») → мессенджер → медиа-хостинг.
Связанные документы
../methodology.md— фреймворк секции, построенный на этой статье (§1–4)../classic-designs.md— эталонный разбор URL shortener (§1) и остальные билеты../knowledge-base.md— числа и паттерны (latency numbers упомянуты в статье как обязательные)../README.md— индекс папки и план чтения