Анализ производительности запуска Linux
Используйте systemd-analyze, чтобы получить ценную информацию и решить проблемы с производительностью запуска Linux.
Часть работы системного администратора — анализ производительности систем, а также поиск и устранение проблем, которые приводят к снижению производительности и длительному времени запуска. Системным администраторам также необходимо проверить другие аспекты конфигурации и использования systemd.
Система инициализации systemd предоставляет инструмент systemd-analyze
, который может помочь выявить проблемы с производительностью и другую важную информацию systemd. В предыдущей статье Анализ календаря и временных интервалов systemd я использовал systemd-analyze
для анализа временных меток и временных интервалов в таймерах systemd, но у этого инструмента есть много других применений, некоторые из которых Я исследую в этой статье.
Обзор запуска
Последовательность запуска Linux — хорошее место для начала изучения, поскольку многие функции инструмента systemd-analyze
предназначены для запуска. Но сначала важно понять разницу между загрузкой и запуском. Последовательность загрузки начинается с самотестирования BIOS при включении питания (POST) и заканчивается, когда ядро завершает загрузку и берет на себя управление хост-системой, что является началом запуска и моментом начала ведения журнала systemd.
Во второй статье этой серии, Что такое systemd при запуске в Linux, я более подробно обсуждаю запуск с точки зрения того, что происходит и в какой последовательности. В этой статье я хочу изучить последовательность запуска, чтобы определить, сколько времени требуется для запуска и какие задачи занимают больше всего времени.
Результаты, которые я покажу ниже, получены с моей основной рабочей станции, что гораздо интереснее, чем результаты виртуальной машины. Эта рабочая станция состоит из материнской платы ASUS TUF X299 Mark 2, процессора Intel i9-7960X с 16 ядрами и 32 процессорами (потоками) и 64 ГБ оперативной памяти. Некоторые из приведенных ниже команд могут выполняться пользователем без полномочий root, но в этой статье я буду использовать root, чтобы избежать необходимости переключаться между пользователями.
Существует несколько вариантов проверки последовательности запуска. Самая простая форма команды systemd-analyze
отображает обзор количества времени, затраченного на каждый из основных разделов запуска, запуска ядра, загрузки и запуска initrd
( т. е. начальный виртуальный диск, временный образ системы, который используется для инициализации некоторого оборудования и монтирования файловой системы /
[root]), а также пользовательское пространство (где все программы и демоны, необходимые для перевода хоста в состояние полезное состояние загружается). Если команде не передана подкоманда, подразумевается systemd-analyze time
:
[root@david ~]$ systemd-analyze
Startup finished in 53.921s (firmware) + 2.643s (loader) + 2.236s (kernel) + 4.348s (initrd) + 10.082s (userspace) = 1min 13.233s
graphical.target reached after 10.071s in userspace
[root@david ~]#
Наиболее примечательными данными в этих выводах является время, затраченное на прошивку (BIOS): почти 54 секунды. Это невероятное количество времени, и ни одна из моих других физических систем не требует столько времени, чтобы пройти через BIOS.
Мой ноутбук System76 Oryx Pro проводит в BIOS всего 8,506 секунды, а все мои самодельные системы занимают чуть меньше 10 секунд. После некоторых поисков в Интернете я обнаружил, что эта материнская плата известна своим необычайно долгим временем загрузки BIOS. Моя материнская плата никогда не «просто загружается». Он всегда зависает, и мне нужно выполнить цикл выключения и включения питания, а затем BIOS запускается с ошибкой, и мне нужно нажать F1, чтобы войти в конфигурацию BIOS, откуда я могу выбрать загрузочный диск и завершить загрузку. Отсюда и дополнительное время.
Не все хосты показывают данные прошивки. Мои ненаучные эксперименты привели меня к мысли, что эти данные показаны только для процессоров Intel 9-го поколения и выше. Но это может быть неправильно.
Этот обзор процесса загрузки интересен и предоставляет хорошую (хотя и ограниченную) информацию, но о запуске доступно гораздо больше информации, как я опишу ниже.
Назначение вины
Вы можете использовать systemd-analyze Assessment
, чтобы определить, инициализация каких модулей systemd занимает больше всего времени. Результаты отображаются в порядке времени, необходимого для инициализации, от большего к меньшему:
[root@david ~]$ systemd-analyze blame
5.417s NetworkManager-wait-online.service
3.423s dracut-initqueue.service
2.715s systemd-udev-settle.service
2.519s fstrim.service
1.275s udisks2.service
1.271s smartd.service
996ms upower.service
637ms lvm2-monitor.service
533ms lvm2-pvscan@8:17.service
520ms dmraid-activation.service
460ms vboxdrv.service
396ms initrd-switch-root.service
<SNIP – removed lots of entries with increasingly small times>
Поскольку многие из этих служб запускаются параллельно, суммы могут значительно превышать общую сумму, указанную в systemd-analyze time
для всего, что происходит после BIOS. Все это небольшие цифры, поэтому какой-либо существенной экономии я здесь найти не могу.
Данные этой команды могут дать представление о том, какие службы можно использовать для сокращения времени загрузки. Неиспользуемые службы можно отключить. Кажется, ни одна служба не занимает слишком много времени во время этой последовательности запуска. Вы можете увидеть разные результаты для каждой загрузки и запуска.
Критические цепи
Как и критический путь в управлении проектами, критическая цепочка показывает критическую по времени цепочку событий, которые происходят во время запуска. Это системные модули, на которые вы хотите обратить внимание, если запуск медленный, поскольку именно они могут вызвать задержки. Этот инструмент не отображает все запускаемые юниты, а только те, которые находятся в этой критической цепочке событий:
[root@david ~]# systemd-analyze critical-chain
The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.
graphical.target @10.071s
└─lxdm.service @10.071s
└─plymouth-quit.service @10.047s +22ms
└─systemd-user-sessions.service @10.031s +7ms
└─remote-fs.target @10.026s
└─remote-fs-pre.target @10.025s
└─nfs-client.target @4.636s
└─gssproxy.service @4.607s +28ms
└─network.target @4.604s
└─NetworkManager.service @4.383s +219ms
└─dbus-broker.service @4.434s +136ms
└─dbus.socket @4.369s
└─sysinit.target @4.354s
└─systemd-update-utmp.service @4.345s +9ms
└─auditd.service @4.301s +42ms
└─systemd-tmpfiles-setup.service @4.254s +42ms
└─import-state.service @4.233s +19ms
└─local-fs.target @4.229s
└─Virtual.mount @4.019s +209ms
└─systemd-fsck@dev-mapper-vg_david2\x2dVirtual.service @3.742s +274ms
└─local-fs-pre.target @3.726s
└─lvm2-monitor.service @356ms +637ms
└─dm-event.socket @319ms
└─-.mount
└─system.slice
└─-.slice
[root@david ~]#
Цифры, которым предшествует @
, показывают абсолютное количество секунд с момента начала запуска, когда устройство становится активным. Числа, которым предшествует +
, показывают количество времени, необходимое устройству для запуска.
Состояние системы
Иногда вам необходимо определить текущее состояние системы. Команда systemd-analyze dump
выгружает огромный объем данных о текущем состоянии системы. Он начинается со списка основных временных меток загрузки, списка каждого модуля systemd и полного описания состояния каждого из них:
[root@david ~]# systemd-analyze dump
Timestamp firmware: 1min 7.983523s
Timestamp loader: 3.872325s
Timestamp kernel: Wed 2020-08-26 12:33:35 EDT
Timestamp initrd: Wed 2020-08-26 12:33:38 EDT
Timestamp userspace: Wed 2020-08-26 12:33:42 EDT
Timestamp finish: Wed 2020-08-26 16:33:56 EDT
Timestamp security-start: Wed 2020-08-26 12:33:42 EDT
Timestamp security-finish: Wed 2020-08-26 12:33:42 EDT
Timestamp generators-start: Wed 2020-08-26 16:33:42 EDT
Timestamp generators-finish: Wed 2020-08-26 16:33:43 EDT
Timestamp units-load-start: Wed 2020-08-26 16:33:43 EDT
Timestamp units-load-finish: Wed 2020-08-26 16:33:43 EDT
Timestamp initrd-security-start: Wed 2020-08-26 12:33:38 EDT
Timestamp initrd-security-finish: Wed 2020-08-26 12:33:38 EDT
Timestamp initrd-generators-start: Wed 2020-08-26 12:33:38 EDT
Timestamp initrd-generators-finish: Wed 2020-08-26 12:33:38 EDT
Timestamp initrd-units-load-start: Wed 2020-08-26 12:33:38 EDT
Timestamp initrd-units-load-finish: Wed 2020-08-26 12:33:38 EDT
-> Unit system.slice:
Description: System Slice
Instance: n/a
Unit Load State: loaded
Unit Active State: active
State Change Timestamp: Wed 2020-08-26 12:33:38 EDT
Inactive Exit Timestamp: Wed 2020-08-26 12:33:38 EDT
Active Enter Timestamp: Wed 2020-08-26 12:33:38 EDT
Active Exit Timestamp: n/a
Inactive Enter Timestamp: n/a
May GC: no
<SNIP – Deleted a bazillion lines of output>
На моей основной рабочей станции эта команда сгенерировала поток из 49 680 строк и размером около 1,66 МБ. Эта команда очень быстрая, поэтому вам не нужно ждать результатов.
Мне нравится богатство деталей, предоставляемых для различных подключенных устройств, таких как хранилище. У каждого модуля systemd есть раздел с подробной информацией, такой как режимы для различных сред выполнения, каталоги кеша и журналов, командная строка, используемая для запуска модуля, идентификатор процесса (PID), временная метка запуска, а также ограничения на память и файлы.
На странице руководства systemd-analyze
показан параметр systemd-analyze --user dump
, который предназначен для отображения информации о внутреннем состоянии менеджера пользователей. Мне это не помогло, и поиск в Интернете показывает, что с этим может быть проблема. В systemd экземпляры --user
используются для управления и контроля ресурсов иерархии процессов, принадлежащих каждому пользователю. Процессы каждого пользователя являются частью группы управления, о которой я расскажу в следующей статье.
Аналитические графики
Большинству начальников с острыми волосами (PHB) и многим хорошим менеджерам красивые графики легче читать и понимать, чем текстовые данные о производительности системы, которые я обычно предпочитаю. Однако иногда даже мне нравится хороший график, и systemd-analyze
предоставляет возможность отображать данные запуска в векторной графической диаграмме SVG.
Следующая команда создает файл векторной графики, в котором отображаются события, происходящие во время загрузки и запуска. Создание этого файла занимает всего несколько секунд:
[root@david ~]# systemd-analyze plot > /tmp/bootup.svg
Эта команда создает SVG, который представляет собой текстовый файл, определяющий серию графических векторов, которые приложения, включая Image Viewer, Ristretto, Okular, Eye of Mate, LibreOffice Draw и другие, используют для создания графика. Эти приложения обрабатывают файлы SVG для создания изображения.
Я использовал LibreOffice Draw для визуализации графика. График огромен, и вам придется значительно увеличить масштаб, чтобы разглядеть какие-либо детали. Вот небольшая часть этого:
(Дэвид Бот, CC BY-SA 4.0)
Последовательность загрузки находится слева от нуля (0) на временной шкале графика, а последовательность запуска — справа от нуля. Эта небольшая часть показывает ядро, initrd
и запущенные процессы initrd
.
На этом графике наглядно показано, что и когда началось, сколько времени потребовалось для запуска, а также основные зависимости. Критический путь выделен красным.
Другая команда, генерирующая графический вывод, — это systemd-analyze dot
. Он генерирует текстовые описания графов зависимостей в формате DOT. Результирующий поток данных затем передается через утилиту dot
, которая является частью семейства программ, которые можно использовать для создания файлов векторной графики из различных типов данных. Эти файлы SVG также можно обрабатывать с помощью инструментов, перечисленных выше.
Сначала сгенерируйте файл. На моей основной рабочей станции это заняло почти девять минут:
[root@david ~]# time systemd-analyze dot | dot -Tsvg > /tmp/test.svg
Color legend: black = Requires
dark blue = Requisite
dark grey = Wants
red = Conflicts
green = After
real 8m37.544s
user 8m35.375s
sys 0m0.070s
[root@david ~]#
Я не буду воспроизводить здесь результат, потому что полученный график представляет собой спагетти. Но вам стоит попробовать и просмотреть результат, чтобы понять, что я имею в виду.
Условные предложения
Одна из наиболее интересных, но несколько общих возможностей, которую я обнаружил, читая справочную страницу systemd-analyze(1)
, — это подкоманда condition
. (Да, я читаю справочные страницы, и это потрясающе, что я узнал таким образом!) Эту подкоманду condition
можно использовать для проверки условий и утверждений, которые можно использовать в файлах модулей systemd.
Его также можно использовать в сценариях для оценки одного или нескольких условий — он возвращает ноль (0), если все условия выполнены, или единицу (1), если какое-либо условие не выполнено. В любом случае он также выдает текст о своих выводах.
Пример ниже со страницы руководства немного сложен. Он проверяет версию ядра между 4.0 и 5.1, что хост работает от сети переменного тока, что архитектура системы не ARM, и что каталог /etc/os-release
существует. Я добавил оператор echo $?
для печати кода возврата.
[root@david ~]# systemd-analyze condition 'ConditionKernelVersion = ! <4.0' \
'ConditionKernelVersion = >=5.1' \
'ConditionACPower=|false' \
'ConditionArchitecture=|!arm' \
'AssertPathExists=/etc/os-release' ; \
echo $?
test.service: AssertPathExists=/etc/os-release succeeded.
Asserts succeeded.
test.service: ConditionArchitecture=|!arm succeeded.
test.service: ConditionACPower=|false failed.
test.service: ConditionKernelVersion=>=5.1 succeeded.
test.service: ConditionKernelVersion=!<4.0 succeeded.
Conditions succeeded.
0
[root@david ~]#
Список условий и утверждений начинается со строки 600 на странице руководства systemd.unit(5)
.
Перечисление файлов конфигурации
Инструмент systemd-analyze
позволяет отправлять содержимое различных файлов конфигурации в STDOUT
, как показано здесь. Базовый каталог — /etc/
:
[root@david ~]# systemd-analyze cat-config systemd/system/display-manager.service
# /etc/systemd/system/display-manager.service
[Unit]
Description=LXDM (Lightweight X11 Display Manager)
#Documentation=man:lxdm(8)
Conflicts=getty@tty1.service
After=systemd-user-sessions.service getty@tty1.service plymouth-quit.service livesys-late.service
#Conflicts=plymouth-quit.service
[Service]
ExecStart=/usr/sbin/lxdm
Restart=always
IgnoreSIGPIPE=no
#BusName=org.freedesktop.lxdm
[Install]
Alias=display-manager.service
[root@david ~]#
Приходится много печатать, чтобы сделать не что иное, как стандартная команда cat
. Я считаю, что следующая команда немного полезна. Он может искать файлы с указанным шаблоном в стандартных расположениях systemd:
[root@david ~]# systemctl cat backup*
# /etc/systemd/system/backup.timer
# This timer unit runs the local backup program
# (C) David Both
# Licensed under GPL V2
#
[Unit]
Description=Perform system backups
Requires=backup.service
[Timer]
Unit=backup.service
OnCalendar=*-*-* 00:15:30
[Install]
WantedBy=timers.target
# /etc/systemd/system/backup.service
# This service unit runs the rsbu backup program
# By David Both
# Licensed under GPL V2
#
[Unit]
Description=Backup services using rsbu
Wants=backup.timer
[Service]
Type=oneshot
Environment="HOME=/root"
ExecStart=/usr/local/bin/rsbu -bvd1
ExecStart=/usr/local/bin/rsbu -buvd2
[Install]
WantedBy=multi-user.target
[root@david ~]#
Обе эти команды предваряют содержимое каждого файла строкой комментария, содержащей полный путь и имя файла.
Проверка файла модуля
После создания нового файла модуля может быть полезно проверить правильность его синтаксиса. Это то, что делает подкоманда verify
. Он может перечислять неправильно написанные директивы и указывать отсутствующие сервисные единицы:
[root@david ~]# systemd-analyze verify /etc/systemd/system/backup.service
В соответствии с философией Unix/Linux, согласно которой «молчание — золото», отсутствие выходных сообщений означает, что в сканируемом файле нет ошибок.
Безопасность
Субкоманда security
проверяет уровень безопасности указанных служб. Он работает только со служебными модулями, но не с другими типами файлов модулей:
[root@david ~]# systemd-analyze security display-manager
NAME DESCRIPTION >
✗ PrivateNetwork= Service has access to the host's network >
✗ User=/DynamicUser= Service runs as root user >
✗ CapabilityBoundingSet=~CAP_SET(UID|GID|PCAP) Service may change UID/GID identities/capabilities >
✗ CapabilityBoundingSet=~CAP_SYS_ADMIN Service has administrator privileges >
✗ CapabilityBoundingSet=~CAP_SYS_PTRACE Service has ptrace() debugging abilities >
✗ RestrictAddressFamilies=~AF_(INET|INET6) Service may allocate Internet sockets >
✗ RestrictNamespaces=~CLONE_NEWUSER Service may create user namespaces >
✗ RestrictAddressFamilies=~… Service may allocate exotic sockets >
✗ CapabilityBoundingSet=~CAP_(CHOWN|FSETID|SETFCAP) Service may change file ownership/access mode/capabilities unres>
✗ CapabilityBoundingSet=~CAP_(DAC_*|FOWNER|IPC_OWNER) Service may override UNIX file/IPC permission checks >
✗ CapabilityBoundingSet=~CAP_NET_ADMIN Service has network configuration privileges >
✗ CapabilityBoundingSet=~CAP_SYS_MODULE Service may load kernel modules
<SNIP>
✗ CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG Service may issue vhangup() >
✗ CapabilityBoundingSet=~CAP_WAKE_ALARM Service may program timers that wake up the system >
✗ RestrictAddressFamilies=~AF_UNIX Service may allocate local sockets >
→ Overall exposure level for backup.service: 9.6 UNSAFE ?
lines 34-81/81 (END)
Да, смайлик является частью вывода. Но, конечно, многим службам для выполнения своей работы необходим практически полный доступ ко всему. Я запустил эту программу для нескольких служб, включая мою собственную службу резервного копирования; результаты могут отличаться, но суть, по-видимому, в основном та же самая.
Этот инструмент будет очень полезен для проверки и исправления сервисных единиц пользовательского пространства в средах, критически важных для безопасности. Я не думаю, что он может что-то предложить большинству из нас.
Последние мысли
Этот мощный инструмент предлагает несколько интересных и удивительно полезных опций. Большая часть того, что рассматривается в этой статье, посвящена использованию systemd-analyze
для получения информации о производительности запуска Linux с помощью systemd. Он также может анализировать другие аспекты systemd.
Некоторые из этих инструментов имеют ограниченное применение, а о паре следует вообще забыть. Но большинство из них можно эффективно использовать при решении проблем с запуском и другими функциями systemd.
Ресурсы
В Интернете доступно много информации о systemd, но большая ее часть краткая, бестолковая или даже вводящая в заблуждение. В дополнение к ресурсам, упомянутым в этой статье, следующие веб-страницы предлагают более подробную и достоверную информацию о запуске systemd. Этот список увеличился с тех пор, как я начал эту серию статей, чтобы отразить проведенные мной исследования.
- Страница руководства systemd.unit(5) содержит хороший список разделов юнит-файла и параметров их конфигурации, а также краткое описание каждого из них.
- В проекте Fedora есть хорошее практическое руководство по systemd. В нем есть практически все, что вам нужно знать для настройки, управления и обслуживания компьютера Fedora с помощью systemd.
- В проекте Fedora также есть хорошая шпаргалка, в которой есть перекрестные ссылки на старые команды SystemV и сопоставимые команды systemd.
- Документация Red Hat содержит хорошее описание файловой структуры модуля, а также другую важную информацию.
- Подробную техническую информацию о systemd и причинах его создания можно найти в описании systemd на сайте Freedesktop.org.
- «Больше удовольствия от systemd» на Linux.com предлагает более подробную информацию и советы по systemd.
Существует также серия глубоко технических статей для системных администраторов Linux Леннарта Поеттеринга, дизайнера и основного разработчика systemd. Эти статьи были написаны в период с апреля 2010 по сентябрь 2011 года, но сейчас они так же актуальны, как и тогда. Большая часть всего хорошего, что было написано о systemd и его экосистеме, основано на этих статьях.
- Переосмысление ПИД 1
- systemd для администраторов, часть I
- systemd для администраторов, часть II
- systemd для администраторов, часть III
- systemd для администраторов, часть IV
- systemd для администраторов, часть V
- systemd для администраторов, часть VI
- systemd для администраторов, часть VII
- systemd для администраторов, часть VIII
- systemd для администраторов, часть IX
- systemd для администраторов, часть X
- systemd для администраторов, часть XI