Вы написали Prowid Photos — приложение, где люди выкладывают фотографии и подписываются друг на друга. На ноутбуке и на десяти знакомых всё летает. Но что будет, когда придёт миллион человек в день? Хватит ли одного сервера и что случится, если он упадёт в пятницу вечером? Системный дизайн — это умение отвечать на такие вопросы до того, как они превратятся в аварии. В этом уроке научимся записывать требования в цифрах, разберёмся с задержкой, пропускной способностью и «девятками» доступности и освоим расчёт «на салфетке».

Что такое системный дизайн

Системный дизайн — это выбор частей системы (клиент, API, база данных, кеш, очередь, файловое хранилище), способов их общения и ответ на вопрос: что сломается первым, когда нагрузка вырастет. Идеальных решений здесь нет, есть компромиссы (trade-offs): быстрее или дешевле, проще или надёжнее.

Аналогия — кухня. Для семьи из четырёх человек и для ресторана на 500 мест кухни проектируют по-разному, но сначала нужно узнать, сколько гостей придёт и что они будут есть. Поэтому разбор любой системы идёт в четыре шага:

  1. Требования — что система должна делать и насколько хорошо.
  2. Оценки — сколько запросов, данных и трафика ожидаем.
  3. Компоненты — из чего собираем и как части связаны.
  4. Узкие места — что упрётся в потолок первым и как это масштабировать.

Этот урок — про шаги 1 и 2, остальной модуль — про шаги 3 и 4.

Шаг 1. Требования: что делаем и насколько хорошо

Функциональные требования описывают, что система умеет: загрузить фото, подписаться на пользователя, поставить лайк, открыть ленту. Нефункциональные — насколько хорошо она это делает: как быстро открывается лента, сколько времени в году сервис может быть недоступен, сколько пользователей выдержит, не потеряются ли снимки. Именно они определяют архитектуру: «загрузить фото» можно написать за выходные, а «загрузить так, чтобы фото не потерялось, при миллионе пользователей и доступности 99,9%» — это задача на месяцы.

От идеи к цифрам: функциональные и нефункциональные требования
От идеи к цифрам: функциональные и нефункциональные требования

Типичная ошибка новичков — формулировать нефункциональные требования словами: «быстро», «надёжно», «для многих». Такое требование нельзя ни проверить, ни спроектировать. Превратите каждое слово в число:

ts
// Prowid Photos: requirements as numbers, not wishes
const functional = [
  'upload a photo',
  'follow other users',
  'like and comment',
  'open a feed of the people I follow',
];

const nonFunctional = {
  feedLatencyP95Ms: 300, // 95% of feed requests are faster than this
  availabilityPercent: 99.9, // about 8.8 hours of downtime per year
  dau: 1_000_000, // daily active users
  peakRps: 350, // the busiest second of the day
  feedFreshnessSeconds: 10, // a new photo shows up within 10 s
  photosAreNeverLost: true, // durability matters more than speed
};

Вопросы, которые стоит задать заказчику (или себе) до первой строчки кода: