Вы написали Prowid Photos — приложение, где люди выкладывают фотографии и подписываются друг на друга. На ноутбуке и на десяти знакомых всё летает. Но что будет, когда придёт миллион человек в день? Хватит ли одного сервера и что случится, если он упадёт в пятницу вечером? Системный дизайн — это умение отвечать на такие вопросы до того, как они превратятся в аварии. В этом уроке научимся записывать требования в цифрах, разберёмся с задержкой, пропускной способностью и «девятками» доступности и освоим расчёт «на салфетке».
Что такое системный дизайн
Системный дизайн — это выбор частей системы (клиент, API, база данных, кеш, очередь, файловое хранилище), способов их общения и ответ на вопрос: что сломается первым, когда нагрузка вырастет. Идеальных решений здесь нет, есть компромиссы (trade-offs): быстрее или дешевле, проще или надёжнее.
Аналогия — кухня. Для семьи из четырёх человек и для ресторана на 500 мест кухни проектируют по-разному, но сначала нужно узнать, сколько гостей придёт и что они будут есть. Поэтому разбор любой системы идёт в четыре шага:
- Требования — что система должна делать и насколько хорошо.
- Оценки — сколько запросов, данных и трафика ожидаем.
- Компоненты — из чего собираем и как части связаны.
- Узкие места — что упрётся в потолок первым и как это масштабировать.
Этот урок — про шаги 1 и 2, остальной модуль — про шаги 3 и 4.
Шаг 1. Требования: что делаем и насколько хорошо
Функциональные требования описывают, что система умеет: загрузить фото, подписаться на пользователя, поставить лайк, открыть ленту. Нефункциональные — насколько хорошо она это делает: как быстро открывается лента, сколько времени в году сервис может быть недоступен, сколько пользователей выдержит, не потеряются ли снимки. Именно они определяют архитектуру: «загрузить фото» можно написать за выходные, а «загрузить так, чтобы фото не потерялось, при миллионе пользователей и доступности 99,9%» — это задача на месяцы.
Типичная ошибка новичков — формулировать нефункциональные требования словами: «быстро», «надёжно», «для многих». Такое требование нельзя ни проверить, ни спроектировать. Превратите каждое слово в число:
// 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
};Вопросы, которые стоит задать заказчику (или себе) до первой строчки кода: