Работая в одном из крупнейших банков страны мне пришлось столкнутся с задачей оценки эффективности использования ресурсов примерно 16 тысяч серверов. Задача была сформулирована предельно просто — нужно было разработать методологию оценки метрик загрузки сервера за период. В идеале оценка загрузки сервера за период должна производится по одному или нескольким (не более 8) числам.

Несколько слов об особенностях использования виртуальных серверов


В больших организациях (особенно в банках) есть разношерстный зоопарк legacy-приложений, развернутых на разных серверах с помощью разнообразных технологий виртуализации. Частное облако это перспективная технология, но в реальности крупные организации еще долго будут использовать различные платформы виртуализации для развертывания разнообразных приложений.

По мере развития платформ виртуализации наступает момент, когда никто в компании не может понять насколько эффективно используются ресурсы. Даже самые развитые средства мониторинга не дают ответ на этот вопрос из-за различных сценариев использования серверов. Например, в департаменте может быть сервер отчетов, который будет полностью загружен только ограниченный период времени. Скажем, часа 3-4 в конце месяца. В реальных сценариях динамически ресурсы для таких серверов никто не выделяет — это сложно технически и организационно. Ресурсы выделяются именно под максимальную периодическую загрузку сервера, хоть она и бывает нечасто.

Как резюме — в крупных организациях ресурсы виртуальных ферм расходуются крайне неэффективно.

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

Методология


Для оценки загруженности ресурсов необходимо собирать статистику разнообразных счетчиков, для оценки загруженности ресурсов будут использоваться различные метрики. Условно счетчики можно разделить на 2 типа (по скорости изменения): “быстрые” и “медленные”. Хорошим примером “быстрого” счетчика является счетчик загрузки процессора (%CPU). Примером медленного счетчика служит объем свободного места жесткого диска в процентах (%FreeSpace).
Оценка медленных счетчиков заключается в вычислении экстремального (минимального или максимального) значения метрики за период. Такой подход позволяет (например, при оценке свободного места диска) оценить свободный ресурс и, при необходимости, выделить дополнительные объемы или уменьшить текущие.

Для быстрых счетчиков используется другой подход. Недостатки использования простых интегральных метрик (среднее, максимум, минимум и медиана) для оценки динамики таких счетчиков хорошо описаны здесь. К общим недостаткам можно отнести отсутствие информации о повышенных нагрузках (средних и пиковых). Если в качестве интегральной метрики брать максимальное значение за период, то наличие выбросов (например мгновенная загрузка CPU до 100% при запуске программы) не даст объективной информации.

В статье предлагается для оценки быстрой метрики использовать квантиль 0,9 (это значение, которое указывает уровень, ниже которого лежит наблюдаемая величина в 90% отсчетов). При равномерной загрузке сервера по этой метрике мы можем адекватно оценить среднюю загрузку процессора. Но этот подход обладает теми же недостатками — отсутствием информации о повышенных нагрузках (средних и пиковых).

Ниже в качестве иллюстрации недельный и суточный график счетчика %CPU. Максимальное значение счетчика на графиках было 100%.





На графике видно, что в указанный период присутствует всплеск нагрузки, который длится примерно 3 часа. Для этого счетчика был выполнен расчет разнообразных метрик за неделю. Из графика 2 видно, медиана (зеленая линия, значение 5%), среднее (желтая, значение 12%) и квантиль 0,9 (красная, значение 27%) фильтруют изменение нагрузки и информация о ней теряется.

В качестве развития идеи квантилей я хотел бы предложить идею скользящего квантиля. Это аналог скользящей средней, но в качестве оконной функции используется квантиль 0,9. Причем использовать для оценки уровня счетчика мы будем 2 скользящих квантиля — быстрый с небольшим периодом (1 час) и медленный с большим периодом (24 часа). Быстрый квантиль отфильтрует мгновенные выбросы и даст информацию о пиковых нагрузках. Медленный квантиль позволит оценить среднюю нагрузку.

Как видно из графиков скользящие квантили 0,9 это динамические характеристики (коричневый — быстрый, фиолетовый — медленный). Для простоты оценки состояния счетчика в качестве метрик предлагается использовать:

  • максимальное значение квантиля с периодом 1 час, которое показывает максимальную продолжительную нагрузку сервера за период,
  • среднее значение квантиля с периодом 24 часа, которое показывает усредненную нагрузку сервера за период.

На графике максимальное значение быстрого квантиля — черная прямая на уровне 85%, среднее значение медленного квантиля — розовая прямая на уровне 30%.

Таким образом, при анализе загруженности ресурсов сервера (по счетчику %CPU) если брать в качестве метрики среднее за месяц (12%), то можно принять ошибочное решение об уменьшении выделенных ресурсов. Двойная метрика быстрый/медленный скользящий квантиль (85 и 30%) показывает, что выделенных ресурсов достаточно, но излишков нет.

Решение


Реализация оценки эффективности использования ресурсов разложилась на 3 задачи:

  1. сбор данных
  2. разработка методологии оценки
  3. имплементация методологии в текущую архитектуру

Выше я рассмотрел задачу 2 этой реализации, ниже немного поговорим о третьей задаче.

Сбор данных производился в БД ClickHouse. Эта колоночная СУБД идеально подходит для хранения time-series данных. Подробно об этом рассказывалось на ClickHouse Meetup 5 сентября 2019 года. Сравнение ClickHouse с другими time-series DBMS можно посмотреть здесь.
В результате сбора данных у нас образовались несколько таблиц, в которых данные были организованы построчно (значения каждого счетчика записывалась в отдельную строку). И, конечно, с сырыми данными были проблемы.

Первая проблема — неравномерность промежутков между записями счетчика. Например, если стандартным периодом записи счетчика были 5 минут, то иногда встречались пропуски и следующая запись отстояла от предыдущей более чем на 5 минут (до 20 минут).

Вторая проблема — иногда данные о счетчике приходили 2 и более раза (с разными значениями) с одной и той же меткой времени.

И третья проблема — в ClickHouse нет оконных функций.

Для решения первой проблемы можно использовать ASOF JOIN. Идея достаточно проста — для каждого счетчика каждого сервера создать таблицу равномерно с равномерно заполненными интервалами времени. Использование ASOF JOIN позволит заполнить значения в новой таблице ближайшими по времени значениями из таблицы сырых данных (варианты заполнения, аналогичные ffill и bfill можно настроить).

Решение второй проблемы — агрегация с выбором максимального значения в данный момент времени.

Для решения третьей проблемы рассматривались несколько вариантов решений. Первый — скрипт на Python был отвергнут из-за недостаточного быстродействия. Второй вариант решения — копирование сырых данные в БД MSSQL, расчет метрик и копирование обратно — показался слишком сложным для реализации. Также в MSSQL есть оконные функции, но нет нужной агрегатной функции. Можно было бы озадачится и написать свою собственную SQL CLR функцию. Но этот вариант был отвергнут из-за излишней сложности.

Рабочим решением может быть SQL скрипт для ClickHouse. Пример этого скрипта приведен ниже. Для простоты я рассмотрел вычисление только быстрого квантиля для одного счетчика для нескольких серверов. Выглядит решение не очень просто и не очень удобно, но работает.

В итоге в тестовом режиме был создан отчет в PowerBI для демонстрации методологии.





Заключение


В качестве заключения хотелось бы порассуждать о развитии решения. Если посмотреть на решение с точки зрения хранилищ данных, то видно, что таким образом решена задача создания хранилища данных (Data Warehouse) из слоя сырых данных (Staging Area). Можно дискутировать об архитектуре, но для ClickHouse как колоночной базы данных нормализация не критична (а может даже вредна).

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

P.S.

Код и данные для тестирования выложены здесь .