Контекст всегда важен. История проблем производительности
#DevOps
#оптимизация
#производительность
#счетчкики
#Windows
Зачем мы здесь
Процессорные ресурсы и то, как работает с ними операционная система - тема на самом деле не простая. Бывают тривиальные ситуации, когда можно явно установить причины высокой нагрузки на CPU и их быстро исправить. С другой стороны, бывают и сложные случаи. Особенно, если в дело вмешивается виртуализация, проблемы оборудования или драйверов, ошибки в программном коде приложений или даже ядре системы.
Нет, мы не будем рассматривать все возможные проблемы и способы их диагностики в одной публикации. Вместо этого мы начнем с простейшей истории проблем производительности с мощностями CPU. Заодно пройдем по всем доступным счетчикам производительности Windows, которые позволяют диагностировать работу процессорной подсистемы. Большая часть рассмотренных ниже показателей производительности актуальны и для *.nix-систем.
И так, начнем с минимального объема теории.
Не хочу читать
А читать придется, но не много. Рассмотрим основные показатели производительности, которые можно использовать для диагностики работы в части ЦП. Их не много, чуть больше десяти.
% загруженности процессора
Счетчик ”% загруженности процессора” (\Processor Information(_Total)\% Processor Time) - всем известный показатель работы CPU, который можно увидеть в стандартном диспетчере задач.
Показывает процент времени, в котором ЦП выполняет инструкции, то есть выполняет какие-либо задачи. Включает себя % пользовательской нагрузки и % работы в привилегированном режиме.
Вычисляется как 100% - % выполнения инструкций в потоке бездействия. Этот поток бездействия есть у каждого процессора и используется, когда нет другой нагрузки. Показатель является основным и демонстрирует средний % времени занятости CPU за определенное время.
В некоторых случаях может показывать не совсем точные данные, т.к. процессор получает их по использованным ресурсам с определенным интервалом, равным тактам системных часов. В современны процессорах % может быть ниже реальных данных, т.к. CPU может затрачивать значительную часть времени на обработку потоков.
В любом случае, это самый простой показатель для понимания общей нагрузки на CPU. Обычно с него и начинают анализ работы системы в части процессорных ресурсов.
% работы в пользовательском режиме
Счетчик ”% работы в пользовательском режиме” (\Processor Information(_Total)\% User Time) - показатель % времени, которое процессор затрачивает на выполнение полезной нагрузки от Ваших приложений, служб и т.д. То есть то, для чего Вы его и купили сервер (или арендовали, если это облака).
Входит в общий % загруженности процессора.
% работы в привилегированном режиме
Счетчик ”% работы в привилегированном режиме” (\Processor Information(_Total)\% Privileged Time) - показатель % времени, которое процессор тратит на обработку запросов ядра, которые работают в привилегированном режиме.
Также входит в состав общего % загруженности процессора. В нормальной ситуации не превышает значения в 10%, в противном случае пора начать проводить диагностику. Значение под 20% и более - пора бить тревогу!
Для более детального анализа нужно обращаться к таким счетчикам как ”% времени прерываний”, ”% времени DPC”, “Контекстных переключений/с” и некоторым другим.
% времени прерываний
Счетчик ”% времени прерываний” (\Processor Information(_Total)\% Interrupt Time) - показатель % времени, которое процессор затрачивает на обработку прерываний от различных устройств. В этом режиме запускаются только подпрограммы, обслуживающие прерывания (фактически это функции драйверов устройство).
Показатель позволяет неявно отслеживать активность работы устройств, которые эти прерывания создают (системный таймер, драйвера дисков, сетевых адаптеров и других периферийных устройств).
В идеальном мире значения этого показателя не должны превышать 5% или даже 1%. В других случаях можно говорить о потенциальных проблемах с “железом” или драйверами.
Процент времени бездействия
Счетчик “Процент времени бездействия” (\Processor Information(_Total)\% Idle Time) - счетчик показывает сколько % времени тратит ЦП на “ничего неделанье”, то есть фактически простаивает. О нем мы упоминали в описании показателя “% загруженности процессора”.
% времени C1, % времени C2, % времени C3
Счетчики ”% времени C1, % времени C2, % времени C3”:
- \Processor Information(_Total)\% C1 Time
- \Processor Information(_Total)\% C2 Time
- \Processor Information(_Total)\% C3 Time
Интересные счетчики для отслеживания состояния работы ЦП. Они показывают % времени, которое процессор находится в каждом из C-состояний (C-State). Каждое из состояний характеризуется пониженным энергопотреблением, а также различным временем перехода в обычный режим.
Для высоконагруженных систем может быть не очень хорошим показателем, т.к. для выхода из этих режимов нужно время, что может влиять на скорость работы ЦП. Поэтому для серверов часто дают рекомендации выключать режимы энергосбережения.
Показатель входит в общий процент простоя. Все эти состояния позволяют сохранять контекст работы и достаточно быстро к нему возвращаться при выходе из режима энергосбережения. Не все процессоры поддерживают эти режимы работы.
Стоит на них обращать внимание, если даже при низких нагрузках производительность недостаточна.
% времени DPC
Счетчик ”% времени DPC” (\Processor Information(_Total)\% DPC Time) - показатель % времени, которое процессор затрачивает на прием и обслуживание отложенного вызова процедур (Deferred Procedure Call — DPC). Эти вызовы выполняются в привилегированном режиме, поэтому данный показатель входит в рассмотренный выше ”% работы в привилегированном режиме”. Значения этого счетчика всегда небольшие. Иначе можно говорить о проблемах в используемом ПО.
C1-переходов/сек, C2-переходов/сек, C3-переходов/сек
Счетчики “C1-переходов/сек, C2-переходов/сек, C3-переходов/сек”:
- \Processor Information(_Total)\C1 Transitions/sec
- \Processor Information(_Total)\C2 Transitions/sec
- \Processor Information(_Total)\C3 Transitions/sec
Счетчики показывают количество переходов между состояниями за 1 секунду. Выше мы рассматривали % времени в каждом из C-состояний и эти показатели косвенно связаны с количеством переходов. Чем больше таких переходов, тем больше процессор тратит ресурсов на выполнение этих переходов. В последнем случае нужно задуматься об отключении использования этих режимов. Чем меньше таких переходов, тем лучше.
Прерываний/сек
Счетчик “Прерываний/сек” (\Processor Information(_Total)\Interrupts/sec) - показатель количества прерываний за 1 секунду. Косвенно связан с показателем ”% времени прерываний”, который мы рассматривали выше.
При наличии высоких значений можно говорить о потенциальных проблемах с оборудованием или драйверами устройств. Счетчик не включает прерывания DPC, т.к. они учитываются в своем отдельном показателе.
Совместно с показателем ”% времени прерываний” дает более полную картину о влиянии прерываний на общую работу ЦП.
Длина очереди процессора
Счетчик “Длина очереди процессора” (\System\Processor Queue Length) - показатель длины очереди запросов к ЦП. Высокие значения могут говорить о:
- Недостаточной мощности ЦП или количестве ядер.
- Неоптимальной работе ПО, в т.ч. и драйверов. ( Или и первое и второе.
- Переходы между состояниями пониженного энергопотребления (выше об этом говорили)
- И некоторые другие моменты.
Лучше всего анализировать этот показатель в динамике совместно с другой информацией о работе ЦП.
Контекстных переключений/с
Счетчик “Контекстных переключений/с” (\System\Context Switches Per Second). Windows, как и *.nix, является операционной системой вытесняющей многозадачности.. Это значит, что в один и тот же момент может быть запущено множество различных процессов и потоков, между которым ОС должна справедливо (а может и нет) делить ресурсы процессора. Процесс разделения ресурсов выполняется путем прекращения выполнения одной задачи с сохранением информации о ее состоянии и восстановление состояния задачи, к которой переходит процессор. Это и есть переключение контекста, количество которых данный показатель собирает.
Высокие значения могут говорить о большой пропускной способности ЦП в распределении нагрузки. Показатель следует анализировать в динамике, т.к. каждая система индивидуальна в этой части (зависит от ПО, количества ядер и т.д.)
О показателях выше
Это не полный список, но в большинстве случаев достаточно и этого набора показателей. На постоянной основе есть смысл собирать:
- % загруженности процессора
- % работы в пользовательском режиме
- % работы в привилегированном режиме
- Процент времени бездействия
- % времени прерываний
- Длина очереди процессора
- Контекстных переключений/с
Все остальные - по ситуации.
Теперь можно посмотреть на практике как эти показатели себя ведут в тех или иных ситуациях.
Исходная задача
Поставим простую задачу, чтобы было интересней разбираться с перечисленными показателями. Нужно разобраться почему тормозит некоторый сервер, на котором установлен сервер 1С и периодически возникают пиковые нагрузки CPU до 100%. Из основных характеристик сервера - 8 ядер, частота 3.6 GHz, 16 ГБ RAM. Ничего сверхъестественного. Вот так эта нагрузка выглядит в диспетчере задач.
На самом деле найти причину достаточно просто, но мы пойдем сложным путем, пройдя через все счетчики производительности. И так, поехали!
Базовые показатели
В первую очередь посмотрим на три базовых показатели нагрузки на CPU:
% загруженности процессора
% работы в пользовательском режиме
% работы в привилегированном режиме
Вот так появление этой нагрузки выглядит в системном мониторе (он же perfmon).
Как мы видим, общий
Копнем глубже
Дополнительно посмотрим на другие показатели:
% времени DPC
% времени прерываний
Процент времени бездействия
На графике это будет выглядеть так.
Ничего особенного здесь не видим.
Какое состояние
Проверим состояния процессора в части энергосбережения. Может быть дело в этом? (что вряд ли, но взглянем для интереса):
% времени C1, % времени C2, % времени C3 C1-переходов/сек, C2-переходов/сек, C3-переходов/сек
Количество переключений в секунду отображены пунктиром, а проценты сплошной линией. Вот такой получился график.
Переходов в состояние ниже C1 нет, а они бы были самыми дорогими. Если состояние С1 в рабочим режим переходит за ~10 нс, то C2 уже необходимо 100 нс, а для C3 - 50 мкс. В общем, дело точно не в энергосбережении, и это хорошо! Пойдемте дальше.
Все в очередь
Посмотрим как ведет себя показатель
Видимо большую очередь к ЦП, при этом держится она длительное время, хоть значения очереди и изменяются иногда до 0. Получается, что у нашего сервера просто не хватает мощи переваривать взваливаемую на него нагрузку. Но прежде чем пойти посмотреть какие именно процессы виновны в происходящем, посмотрим что
На графике масштаб изначально 0.001, то есть в спокойном состоянии было около 8 тысяч переключений контекста. Затем мы видим резкий всплеск в момент возросшей нагрузки на ЦП, после чего показатель к предыдущим значениям практически не возвращался. То есть явно возросло количество активных потоков, которые требуют процессорных мощностей. Именно поэтому нужно анализировать этот показатель в динамике, чтобы было с чем сравнивать.
Настал момент посмотреть что за процессы все это вытворяют.
Узнаем правду
Перейдем в старый и добрый диспетчер задач и посмотрим какие процессы в ТОП’е. И о чудо!
Это рабочие процессы сервера 1С! Вот это поворот! Идем в консоль кластера, чтобы понять кто и что делает на сервере.
Большое количество фоновых задания. В колонке “Процессорное время” теперь можно отследить кто съедает процессорные ресурсы, но не в нашем случае. И обратите внимание на названия информационных баз в первой колонке. Видите странность? (нет, я не про имена). Да, баз достаточно много, причем фоновое задание запускается каждое в отдельной информационной базе. Но что это за задания?
Идем в журнал регистрации и видим там это.
Да, в каждой информационной базе аналогичная картина - каждую минуту запускается фоновое задание обновления полнотекстового индекса. Но неужели это задание так может нагружать сервер?
В нормальных ситуациях - нет. Но если на сервере столько баз…
В общем, в чем проблема понятна. 100 баз на одном сервере с 8 ядрами. А ведь нагрузку могут создавать не только фоновые задания обновления индекса ППД, но и остальное (отчеты, проведение документов и многое, многое другое). Можно услышать оправдание такой настройки - но базы то не большие и в каждой работает по 1 пользователю. Как мы видим, это далеко не аргумент в создании такой конфигурации.
Какое тут решение? Думаю, Вы и сами догадываетесь о возможных решениях. Можете написать в комментариях, если есть что сказать. Но если Ваш ответ - нужно отключать полнотекстовый поиск, потому что он тормозит, то Вы не правы. Все служит своим целям, поэтому лучше сначала разобраться с настоящими причинами проблем.
Мониторинг и сбор информации
Мы рассмотрели основные показатели CPU и их краткое описание. На небольшом и простом примере вживую увидели как эти показатели меняются. Но заходить на сервер каждый раз и проверять счетчики работы ЦП - дело не благодарное, ведь никогда точно не знаешь в какой момент проблема появится.
Очевидно, что нужен мониторинг на постоянно основе. Решений для этого достаточно много, но самым распространенным остается использование Zabbix. На Инфостарт не одна статья написана по этой теме. Ссылки на них добавил в конце публикации, а также вот еще некоторый материал, который может пригодиться:
- Немного о мониторинге и простой установке Zabbix
- Диагностика работы Zabbix
- Обновляем Zabbix с 4.0 до 5.0 через грабли
Внедрение, развертывание и настройкам мониторинга - отдельная обширная тема. Но, по крайней мере, теперь Вы знаете с чего начать.
История не из мира Highload
Это была простая история с предсказуемой концовкой. Даже можно сказать - очень упрощенная история. Цель была очень проста - показать какие показатели диагностики ЦП имеются в наличии у каждого под рукой и дать им краткое описание. Как бонус, на графиках мы посмотрели их изменение при возникновении пиковых нагрузок и докопались до истины.
В будущем рассмотрим более сложные примеры связанные с виртуализацией, облаками и прочими ужасами современного мира ИТ. А пока что все.
Всего хорошего и производительного!