Designing Data-Intensive Applications Глава 2. Defining Nonfunctional Requirements Вторая глава книги посвящена нефункциональным требованиям к разрабатываемым нами системам. Под нефункциональными требованиями автор подразумевает: - Производительность (Performance) - Надёжность (Reliability) и отказоустойчивость (Fault Tolerance) - Масштабирование (Scalability) - Поддержка (Maintainability) Система может быть полностью корректна с точки зрения функциональных (т.н. бизнес) требований, но неудобна в использования из-за проблем с надёжностью (потеря данных), производительностью (частые “зависания” из-за нагрузки). Поэтому нефункциональным требованиям также необходимо уделять внимание. Мартин во второй главе книги разбирает пример ленты из соцсети. Как корректная с т.з. функционала фича может быть абсолютно неюзабельна с точки зрения производительности при росте числа пользователей и постов. Производительность Производительность определяется двумя метриками: 1. Время ответа 2. Пропускная способность Время ответа (response time) — время, затраченное с момента начала запроса до момента получения ответа от системы. Обычно измеряется в секундах, миллисекундах или микросекундах. Чем этот показатель ниже тем производительность выше. Но на него могут влиять факторы не зависящие от самой системы напрямую (например, скорость клиента). Пропускная способность (throughput) — максимальное количество запросов или единиц (МБ, ГБ, ТБ) данных в секунду, которое система способна обработать. Чем выше показатель тем производительность системы лучше. С точки зрения конечного пользователя лучшая метрика это время ответа от системы. Именно она влияет на положительный опыт взаимодействия с ней. Пропускная способность системы же определяет возможности вычислительных ресурсов системы (железа, производительности кода). Есть ещё одна метрика, которую часто путают с временем ответа это задержка (latency). Автор пишет, что эти два термина зачастую используют как взаимозаменяющие, но на практике задержка означает время, необходимое для доставки сетевых пакетов до пункта назначения и обратно (после обработки запроса). То есть, время ответа уже включает в себя время задержки, т.е. response time > latency практически всегда. Для измерения производительности используется базовая статистика, а именно: - Арифметическое среднее (Mean) - Медиана (Median) - Процентиль (Percentile) Использовать арифметическое среднее для измерения времени ответа некорректно (но применимо для измерения пропускной способности). Оно не даёт объективной картины, т.к. сильно подвержено влиянию выбросов (outliers). Лучше всего подходит процентиль. Медиана, например, является 50-м процентилем (p50). Если, например, медиана времени ответа 200мс, то это значит что 50% пользователей получили ответа до 200мс, а остальные 50% от 200мс и выше. Лучше всего использовать p90, p95, p99. Надежность Надёжная система подразумевает что: - Она соответствует ожиданиям пользователя (функциональным) - Корректно обрабатывает ошибки от пользователя (некорректный ввод, нестандартное поведение) - Производительность соответствует ожиданиям пользователя - Защищает от несанкционированного доступа к личным данным Отказоустойчивая система подразумевает, что в случае выхода из строя части системы она продолжает свою работу. Например, отказ работы одного из жестких дисков или физической машины не должен повлиять на работоспособность приложения. Для проектирования отказоустойчивых систем практикуют т.н. Chaos Engineering. Это инженерная дисциплина, направленная на проверку надёжности распределенных систем через регулярное внедрение преднамеренных сбоев (увеличение сетевых задержек, отключение серверов и т.д.)