Архитектурные компромиссы

Базовый System Design
≈ 2 мин чтения

В архитектуре почти ничего не бывает бесплатно

System Design редко сводится к поиску решения, у которого есть только плюсы. Каждое заметное улучшение обычно чем-то оплачивается: деньгами, сложностью, задержкой, дополнительной инфраструктурой или ограничениями в других частях системы. Этот обмен и есть архитектурный компромисс.

Один и тот же выбор выглядит по-разному при разных требованиях

Допустим, данные можно держать только в одном экземпляре хранилища. Это просто и дешево, но отказ такого узла способен остановить работу. Добавление копий может повысить устойчивость, зато появляются дополнительные расходы и вопросы синхронизации данных.

Simpler                    More resilient
Client → DB          Client → DB + Replicas
fewer components     more infrastructure
easier to operate    harder to synchronize

Нельзя сказать, что второй вариант всегда «правильнее». Для учебного pet-проекта первый может быть разумным, а для критичного сервиса его риск уже окажется неприемлемым.

Компромисс появляется только относительно цели

Чтобы сравнивать варианты, нужно знать приоритеты системы. Если главное — минимальная задержка, допустимо потратить больше ресурсов. Если важнее низкая стоимость, можно согласиться на более скромный запас по нагрузке. Если потеря данных недопустима, придётся усложнить хранение и восстановление.

Поэтому фраза «эта архитектура лучше» почти всегда требует продолжения: лучше для каких требований?

Частые оси компромиссов

  • простота ↔ гибкость;
  • стоимость ↔ запас производительности;
  • низкая latency ↔ дополнительная согласованность и проверки;
  • быстрая разработка ↔ сложность эксплуатации в будущем;
  • централизация ↔ независимость компонентов;
  • избыточность ↔ расход ресурсов.

Это не готовые формулы. Они помогают заметить цену решения и сформулировать, какое свойство мы улучшаем и чем за это платим.

Как объяснять выбранное решение

Сильное обоснование обычно состоит из трёх частей: требование, решение и цена решения.

Requirement: the service must survive the loss of one instance.
Decision:    run multiple application instances.
Cost:        more infrastructure and more complex operations.

Такой формат полезнее, чем просто перечислять технологии. Он показывает причинно-следственную связь и позволяет пересмотреть архитектуру, если требования позже изменятся.

Хорошая архитектура — не та, где больше компонентов. Это архитектура, в которой компромиссы осознаны и соответствуют требованиям. Дальше мы начнём добавлять к этому мышлению количественную оценку нагрузки.