Сегодня мы рассмотрим сбор и визуализацию метрик производительности Red Hat Enterprise Linux 8 с помощью инструментов Performance Co-Pilot (PCP), Grafana и Bpftrace, а также новые возможности по контролю производительности, которые появились в веб-консоли RHEL 8.4. В наших примерах мы будем использовать следующую конфигурацию: Два сервера RHEL 8.3 (с      именами server-1 и server-2). Grafana версии      grafana-6.7.4-3.el8.x86_64. PCP версии      pcp-5.1.1-3.el8.x86_64. По умолчанию Performance Co-Pilot не устанавливается вместе с RHEL 8, поэтому его надо инсталлировать самостоятельно. Установим его на server-1 и server-2, выполнив на них следующую команду: После того, как Performance Co-Pilot установлен и запущен, можно посмотреть, какие встроенные метрики производительности он предлагает: Вывести значения нужной метрики можно командой pmrep: Опция -s 5 в примере выше говорит, что мы хотим вывести на экран только 5 первых значений метрики. Чтобы метриками могли пользоваться другие приложения, надо включить pmproxy и открыть соответствующий порт на межсетевом экране: Итак, Performance Co-Pilot установлен и настроен, теперь пора заняться Grafana, чтобы перейти к визуализации метрик. Установим grafana на server-1, выполнив на нем следующие команды: Теперь в браузере откроем http://server-1:3000 и залогинимся как пользователь admin с паролем admin. Это пароль по умолчанию и после первого входа его будет предложено заменить на более безопасный. Далее, в панели слева надо щелкнуть значок с шестеренкой, чтобы перейти в настройки (Configuration), и там щелкнуть Plugins. Теперь в поле поиска вводим «Performance Co-Pilot App», щелкаем это приложение и затем нажимаем Enable. Опять щелкаем Configuration, затем Data Sources, жмем Add Data Source, наводим курсор на PCP Vector и жмем появившуюся кнопку Select. В открывшейся форме, в секции HTTP вводим «http://localhost:44322» в поле URL, затем жмем Save & Test внизу формы. Если все нормально, то получим сообщение «Data source is working». В панели слева щелкаем значок с квадратиками (Dashboard), затем Manage и потом PCP Vector Host Overview. В открывшейся панели увидим графики метрик для сервера server-1, такие как: CPU Percentage Load Average Memory Utilization Disk Utilization Per-CPU busy (user/system) CPU user%,system%,interrupt%,wait% Scheduler context switches per second and runnable processes. Memory Used/Cached/Free/Page Fault Rate/Hard Fault Rate Network throughput in/out Network drops in/out Network packets in/out TCP connections/timeouts/close-waits/time wait/established/listen errors/retransmits Disk latency/iops/throughput/utilization Таким образом, мы получили весьма разностороннюю контрольную панель для отслеживания метрик производительности локального хоста в реальном времени. Теперь разберем, как использовать pmseries и Redis, чтобы сохранять данные производительности нескольких хостов и анализировать их в ретроспективе. Итак, у нас есть два сервера. На server-1 будет выполняться Redis и осуществляться сбор метрик PCP со всех наших хостов (в данном случае двух). Поэтому на server-1 должно быть достаточно места для базы данных Redis. При установке PCP по умолчанию это означает примерно 100 МБ на диске и 200 МБ ОЗУ на каждый контролируемый хост. Механизм, отвечающий за хранение данных в БД Redis, называется pmseries, и чтобы установить его на server-1, подредактируем файл /etc/pcp/pmproxy/pmproxy.conf, чтобы в секции [pmproxy] было прописано следующее: Затем, в этом же файле, в секции [pmseries] надо прописать: Далее, чтобы установить, запустить и на постоянку включить Redis на server-1, выполним на нем следующие команды: После чего надо перезапустить несколько сервисов: Всё, теперь server-1 будет писать в базу метрики производительности всех хостов, на которые настроен pmlogger. Пока что pmlogger сконфигурирован только в расчете на server-1, поэтому надо произвести настройку и для server-2.  Для этого на server-2 в файле /etc/sysconfig/pmcd изменим дефолтное значение параметра PMCD_LOCAL с 1 на 0, чтобы разрешить удаленные подключения к сервису pmcd: Теперь разрешим подключение на уровне сервисов: Еще надо разрешить привязку pcp к портам unreserved: И наконец, остается перезапустить сервисы pcp: Теперь server-2 настроен таким образом, что к нему может подключаться агент pmlogger и запрашивать логи. Возвращаемся на server-1 и говорим агенту pmlogger, что у нас есть server-2. Для этого открываем файл /etc/pcp/pmlogger/control.d/remote и добавляем туда следующую строку: Перезапускаем pmlogger: После чего для проверки выполним следующие команды: Если все нормально, то мы увидим файл, заканчивающийся на «.0»: Таким образом, мы проверяем, что server-1 может собирать pcp-метрики с server-2. Теперь возвращаемся в Grafana (http://server-1:3000) и смотрим, как работать с метрикам, собранными через redis. Щелкаем Configuration, затем Data Sources, затем Add Data Source. Наводим курсор на PCP Redis и жмем появившуюся кнопку Select. В открывшейся форме, в секции HTTP вводим «http://localhost:44322» в поле URL, и затем жмем Save & Test внизу формы. Если все нормально, то получим сообщение «Data source is working». На этом настройка закончена и пора смотреть, как все работает. Щелкаем значок Dashboard, затем Manage и затем щелкаем опцию PCP Redis Host Overview. По умолчанию панель PCP Redis Host Overview показывает данные за последние шесть часов, но этот интервал можно укоротить. Метрики следующие: load average memory utilization per-cpu busy (user/sys) context switches per second runnable processes memory (used/cached/free) network throughput in/out network drops in/out network packets in/out tcp timeouts/listen errors/retransmits disk latency/iops/throughput/utilization Как видите, прямо из коробки можно получить уйму полезных данных по всем хостам, метрики которых пишутся в базу данных Redis. Кстати, хост, отображаемый на экране, выбирается с помощью раскрывающегося меню Host в левом верхнем углу. Таким образом, можно вести мониторинг на уровне хостов в реальном времени, а также анализировать данные в ретроспективе. Вы   можете полностью автоматизировать процедуру установки и настройки, сбора и   визуализации метрик, воспользовавшись системной ролью ansible – rhel-system-roles.metrics , которая входит в состав дистрибутива: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/administration_and_configuration_tasks_using_system_roles_in_rhel/monitoring-performance-using-rhel-system-roles_administration-and-configuration-tasks-using-system-roles-in-rhel#introduction-to-the-metrics-role_monitoring-performance-using-rhel-system-roles Теперь покажем, как использовать Performance Co-Pilot вместе с bpftrace для визуализации низкоуровневых метрик ядра, которые обычно не видны стандартными средствами Linux. Вообще говоря, если с помощью сценария bpftrace из ядра Linux можно извлечь какое-то значение для карт eBPF (обобщенная структура «ключ-значение, которая используется для хранения данных в программах eBPF), то это все можно визуализировать с помощью Performance Co-Pilot. Для начала посмотрим, как сконфигурировать наше dev-окружение для работы с bpftrace и Performance Co-Pilot. Итак, Performance Co-Pilot и Grafana у нас уже настроены и работают. Теперь установим на server-1 модуль pcp-pmda-bpftrace, выполним на нем следующие команды: Проверим, что bpftrace pmda установился правильно, запустив следующую команду: Если все хорошо, то мы должны получить результаты пяти замеров (в микросекундах): Теперь, когда bpftrace pmda работает с Performance Co-Pilot, можно начинать интегрировать их вместе с Grafana. Пока что мы разберем это на примере dev-среды, а к продакшну вернемся позже.  Сначала предоставим доступ, создав в пользователя Performance Co-Pilot с именем metrics: Команда saslpasswd2 задает пароль, который мы будем использовать, и добавляет пользователя metrics в sasl-группу pmcd, чтобы он имел доступ к данным pcp. Также надо, чтобы в файле /etc/sasl2/pmcd.conf были две следующие строки: Перезапустим pcp: Теперь надо настроить bpftrace pmda так, чтобы этот только что созданный пользователь мог его использовать его. ВНИМАНИЕ: этот шаг предназначен только для целей разработки, но не для продакшн. Для этого отредактируем файл /var/lib/pcp/pmdas/bpftrace/bpftrace.conf , чтобы в секции [dynamic_scripts] были два следующих элемента: После чего надо переустановить bpftrace pmda: Теперь в браузере можно открыть Grafana (http://server-1:3000) и войти в систему как пользователь admin (пароль которого мы задали выше). В интерфейсе Grafana щелкните значок Configuration, затем Data Sources, затем Add Data Source, прокрутите вниз до элемента PCP bpftrace, наведите на него курсор и щелкните появившуюся кнопку Select. В поле URL введите «http://localhost:44322», в поле Auth выберите Basic auth, в появившейся секции Basic Auth Details введите имя пользователя metrics и пароль, заданный ранее через команду saslpasswd2. После чего щелкнитеSave & Test, и, если все нормально, вы должны получить сообщение «Data source is working». Теперь щелкните значок Dashboards и затем Manage. В списке появится панель с именем PCP bpftrace System Analysis, щелкните ее. Здесь есть несколько метрик. Щелкните стрелку вниз рядом с CPU usage и нажмите Edit. Здесь вы увидите запрос, который представляет собой реальный bpftrace-сценарий, и в данном случае он наполняет bpf-карту @cpu данными по использованию процессора. Grafana просто берет эту bpf-карту и визуализирует ее. Теперь посмотрим, как можно использовать сценарии bpftrace для визуализации данных ядра, таких как количество pid в секунду, представленных через fork. Для этого есть готовый сценарий pidpersec.bt и его ключевой фрагмент, который нам нужен, следующий: По сути, этот сценарий считает количество вызовов sched_process_fork и пишет его в карту bpf, которую мы затем визуализируем с помощью Grafana. Теперь создадим свою панель, которая и будет все это отображать. Возвращаемся на панель PCP bpftrace System Analysis и жмем кнопку Add Panel, после чего на экране появляется новая панель с двумя кнопками, жмем Add Query. Рядом с надписью Query есть раскрывающийся список, выбираем в нем PCP bpftrace, и в текстовом поле Query A вводим следующий сценарий bpftrace: Теперь нажимаем конфигурационную кнопку General и задаем имя панели – «Processes Per Second». После чего возвращаемся в основное окно PCP bpftrace System Analysis и видим, что эта метрика появилась на панели. При желании эту панель можно сохранить. Это всё здорово, но нам пришлось предоставить пользователю grafana доступ к пользователю метрик pcp, и теперь он может запускать в системе любой сценарий bpftrace. Это не страшно в dev-среде, но никак не годится для продакшн. Поэтому нам нужен другой способ предоставлять пользователям наш bpftrace-сценарий, который бы не позволял им запускать любые другие сценарии bpftrace. Сделать это можно с помощью пакета bpftrace pmda. Сценарии bpftrace, хранящиеся в /var/lib/pcp/pmdas/bpftrace/autostart, загружаются как обычные метрики Performance Co-Pilot в тот момент, когда загружается bpftrace pmda.  Поэтому отредактируем файл /var/lib/pcp/pmdas/bpftrace/autostart/pidpersec.bt следующим образом: Сохраним его, и затем выполним следующий команды: Вывод должен быть примерно такой: Поскольку мы не задали имя нашей bpf-карты, pmda именует ее как root. Именно этого мы и добивались, и теперь мы можем обращаться к ней с запросами: И получать ответ вроде такого: Теперь эти метрики можно взять и визуализировать средствами grafana, не предоставляя grafana-пользователю каких-то особых привилегий, поскольку теперь это стандартные метрики Performance Co-Pilot. Для этого вернемся в Grafana, щелкнем значок Dashboards, затем Manage, затем PCP Vector Host Overview, затем Add Panel и в новой панели нажмем кнопкуAdd Query. В раскрывающемся меню рядом с надписью Query выберем PCP Vector и в поле A-запроса введем следующее: Теперь щелкаем значок General и вводим имя «Processes per Second». Возвращаемся на панель PCP Vector Host Overview и видим там график по bpf-карте, которая генерируется нашим сценарием bpftrace обычным пользователем без каких-то особых разрешений. Теперь все это можно использовать в продакшн. Именно так связку pcp-pmda-bpftrace можно использовать для предоставления метрик Linux-ядра системе визуализации Grafana. Надо отметить, что работа через сценарии bpftrace означает, что они будут выполняться все время, постоянную создавая дополнительную нагрузку. Поэтому этот аспект тоже надо контролировать. Ниже мы рассмотрим некоторые из улучшений RHEL 8.4 в плане контроля производительности, которые упрощают поиск и устранение неисправностей, предлагают улучшенную визуализацию, помогают быстрее и лучше оценивать состояние систем. Представьте, что у вас есть всего пара минут, чтобы проанализировать текущие или ретроспективные данные производительности процессора, памяти, дисков и сети, оценить степень использования и перегруженности (saturation) этих ресурсов, а также количество ошибок. Возможно ли это? Да, возможно. Новая веб-консоль RHEL 8.4 позволяет мгновенно увидеть ключевые показатели производительности, быстрее и четче понять, с чего стоит начать устранение проблем, касающихся как локальной системы, так и сетевого окружения. Метрики производительности можно найти в консоли, в разделе System -> Overview - Usage card. Для просмотра исторических данных необходимо установить пакет cockpit-pcp (см. выше), это можно сделать прямо на экране Usage card.  Новый интерфейс консоли разделен на две секции. В верхней части экрана расположены четыре плитки Usage card, отображающие текущие показатели производительности процессора, памяти, дисков и сети: На плитке CPU отображается утилизация и перегрузка процессорных ресурсов, а также топ наиболее активных процессов. Плитка памяти показывает, как используется ОЗУ и файл подкачки, а также основные сервисы-потребители памяти. На плитке дисков собраны IO-метрики чтения-записи, а также процент занятых дисковых ресурсов. Плитка сети показывает сетевой ввод-вывод по каждому сетевому интерфейсу. Нижняя часть экрана, при условии, что у вас установлена и включена коллекция метрик pcp (мы рассматривали это в начале статьи), выглядит примерно так: Здесь представлены данные производительности, от самых последних до тех, что были собраны несколько недель назад. Слева отображается список событий, которые могут представлять интерес с точки зрения производительности; время событий синхронизируется с часами часам локальной машины. Четыре диаграммы справа – это визуализация метрик процессора, памяти, дисков и сети. Слева от вертикальной оси отображаются показатели использования, справа –  показатели перегруженности (saturation). При наведении курсора на диаграмму появляется подсказка с точным значением в соответствующий момент времени. Эти диаграммы помогают лучше понять, на что обратить внимание при устранении проблем производительности, а также отследить время, когда они стали проявляться. Иногда для того, чтобы локализовать первоисточник проблем производительности, требуется углубиться в детали, которых просто нет в новой веб-консоли RHEL. На этот случай в RHEL есть специальные диаграммы производительности процессора, которые называются flame graphs. Они позволяют спрофилировать, кто потребляет процессорные циклы, и быстро определить, где именно этих циклов тратится чересчур много. Важный момент: это делается быстро, просто и наглядно, а не через просмотр бесконечных экранов с данными трассировки стека, как раньше. Прежде чем читать дальше, убедитесь, что у вас на сервере установлены пакеты perf и js-d3-flame-graph. Собрать данные для flame graph можно с помощью команды perf. Для этого ее надо запустить, как показано ниже, дать поработать, скажем, 30 секунд, и затем остановить сбор данных, нажав Ctrl+C в терминале. Чтобы затем выдать собранные данные в flame graph, надо запустить следующую команду: Она выдаст на экран следующее: Теперь открываем в браузере файл flamegraph.html, и видим там примерно следующее: Эта диаграмма визуализирует 30 секунд работы процессора, который профилировался командой perf. Если разбирать ее по вертикали снизу-вверх, то мы видим поток стековых трасс. По горизонтали же отложены процессорные циклы, потраченные на тот или иной элемент диаграммы. Стеки уровня ядра имеют оранжевый цвет, а стеки user space – более теплый оттенок. В самой нижней полоске диаграммы написано root, это корень деревьев стековых фреймов. Двигаясь по диаграмме снизу-вверх, мы видим следующие процессы: SetroubleshootP, mysqld, apache2, 240998, rpm, ksoftirqd, kworker, grafana-server и redis-server. Если слегка позумить (все фреймы стека можно щелкать), то увидим, что большая часть «красной» активности на хосте относиться к mysqld. Программные решения с открытым исходным кодом