В чем важность понимания дизайна современных распределенных систем?
На текущий момент, несмотря на острую нехватку специалистов в области разработки программного обеспечения, требования к ним стремительно растут. Просто “писать код” уже недостаточно, ведь индустрии на данные момент нужны именно инженеры, которые способны решать комплексные инженерные задачи. Если специалист не имеет серьезной теоретической базы, то создать надежное решение – задача, практически невыполнимая. Именно поэтому системный дизайн является важной частью отбора в ведущих компаниях по разработке ПО.
Основные сложности
При создании дизайна систем мы часто сталкиваемся со следующими вызовами:
- Недостаток опыта в построении сложных систем
- Отсутствие теоретической базы
- Отсутствие единого “правильного решения” и необходимость искать компромиссы
Этапы построения системы
- Уточнение требований
Перед началом создания дизайна системы всегда стоит максимально четко определить задачи, которые нам предстоит решить. Это особенно важно ввиду того, что в данном направлении никогда нет единственно верного ответа.
Мы должны четко понимать следующие моменты:
– Детальный функционал системы
– Особенности поиска данных пользователем
– Требования к надежности системы и т.д. - Создание API
Нам необходимо определить интерфейсы взаимодействия нашей системы с внешним миром. Создание этого контракта взаимодействия позволит нам убедиться, что мы не упустили ничего важного.
Например:createUser(username, email, password)
banUser(user_id, reason, timestamp)
- Оценка требуемых ресурсов
При построении распределенных систем крайне важно учитывать то, как мы будем масштабироваться. Мы должны оценить потенциальные нагрузки на систему. Например:
– Требуемый размер хранилища, его тип и требования к надежности (сколько будет пользователей, сколько данных будет генерировать каждый из них и т.д.)
– Вычислительные мощности (количество запросов, соотношение операций чтения и записи и т.д.) - Определение “слабых” мест
Нам стоит выявить потенциальные слабые места системы (так называем bottlenecks) и найти способы их обхода. Например:
– Как мы отслеживаем производительность нашей системы
– Способы уведомления об инцидентах и реагирование на них
– Наличие единой точки отказа и способы ее обхода
– Репликация данных и т.д. - Высокоуровневый дизайн (High Level Design – HLD)
На этом этапе мы, обычно, создаем диаграмму и 5-7 блоков, которые представляют собой ключевые компоненты системы. Для типичной системы такой дизайн будет иметь следующий вид:
Здесь у нас есть клиент (браузер или мобильное приложение). Балансировщик нагрузки, которые перенаправляет запросы на сервера. И хранилища данных. - Низкоуровневый дизайн (Low Level Design – LLD)
После того как мы завершили общий дизайн, обычно, начинается более детальное описание 2-4 (на усмотрение интервьюера) компонентов нашей системы. Ожидается, что кандидат может представить различные подходы к решению задачи и описать их сильные и слабые стороны, после чего сделать аргументированный выбор в пользу одного из них. Обычно, нет единственно верного ответа и мы вынуждены искать компромиссы.
Вывод
Для успешного построения дизайна распределенной системы мы должны следовать заранее намеченному плану и не допускать хаотичного перескакивания между этапами. Пункты, описанные выше всего лишь ориентиры, которые могут помочь вам в этом процессе, но всегда стоит действовать на основании своего опыта и понимания задачи.